libcouchbase 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/ext/libcouchbase/CMakeLists.txt +51 -25
  4. data/ext/libcouchbase/CONTRIBUTING.md +46 -65
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +163 -0
  6. data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +9 -11
  7. data/ext/libcouchbase/cmake/Modules/FindProfiler.cmake +16 -0
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +6 -6
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
  10. data/ext/libcouchbase/cmake/configure +16 -0
  11. data/ext/libcouchbase/example/CMakeLists.txt +17 -2
  12. data/ext/libcouchbase/example/analytics/.gitignore +1 -0
  13. data/ext/libcouchbase/example/analytics/analytics.c +158 -0
  14. data/ext/libcouchbase/example/analytics/build-queries.rb +34 -0
  15. data/ext/libcouchbase/example/analytics/cJSON.c +1 -0
  16. data/ext/libcouchbase/example/analytics/cJSON.h +1 -0
  17. data/ext/libcouchbase/example/analytics/queries.h +113 -0
  18. data/ext/libcouchbase/example/analytics/queries/00-show-dataverse.json +5 -0
  19. data/ext/libcouchbase/example/analytics/queries/01-setup-dataset-breweries.json +6 -0
  20. data/ext/libcouchbase/example/analytics/queries/02-setup-dataset-beers.json +6 -0
  21. data/ext/libcouchbase/example/analytics/queries/03-initiate-shadow.json +6 -0
  22. data/ext/libcouchbase/example/analytics/queries/04-list-datasets.json +7 -0
  23. data/ext/libcouchbase/example/analytics/queries/05-count-breweries.json +5 -0
  24. data/ext/libcouchbase/example/analytics/queries/06-first-brewery.json +6 -0
  25. data/ext/libcouchbase/example/analytics/queries/07-key-based-lookup.json +6 -0
  26. data/ext/libcouchbase/example/analytics/queries/08-exact-match-lookup.json +7 -0
  27. data/ext/libcouchbase/example/analytics/queries/09-exact-match-lookup-different-shape.json +6 -0
  28. data/ext/libcouchbase/example/analytics/queries/10-other-query-filters.json +6 -0
  29. data/ext/libcouchbase/example/analytics/queries/11-equijoin.json +9 -0
  30. data/ext/libcouchbase/example/analytics/queries/12-equijoin-select-star.json +10 -0
  31. data/ext/libcouchbase/example/analytics/queries/13-ansi-join.json +8 -0
  32. data/ext/libcouchbase/example/analytics/queries/14-join-select-values.json +8 -0
  33. data/ext/libcouchbase/example/analytics/queries/15-nested-outer-join.json +7 -0
  34. data/ext/libcouchbase/example/analytics/queries/16-theta-join.json +8 -0
  35. data/ext/libcouchbase/example/analytics/queries/17-existential-quantification.json +9 -0
  36. data/ext/libcouchbase/example/analytics/queries/18-universal-quantification.json +7 -0
  37. data/ext/libcouchbase/example/analytics/queries/19-simple-aggregation.json +6 -0
  38. data/ext/libcouchbase/example/analytics/queries/20-simple-aggregation-unwrapped-value.json +6 -0
  39. data/ext/libcouchbase/example/analytics/queries/21-simple-aggregation-explicit.json +6 -0
  40. data/ext/libcouchbase/example/analytics/queries/22-grouping-and-aggregation.json +6 -0
  41. data/ext/libcouchbase/example/analytics/queries/23-grouping-and-aggregation-with-hint.json +7 -0
  42. data/ext/libcouchbase/example/analytics/queries/24-grouping-and-limits.json +7 -0
  43. data/ext/libcouchbase/example/analytics/queries/25-named-parameters.json +7 -0
  44. data/ext/libcouchbase/example/analytics/queries/26-positional-parameters.json +7 -0
  45. data/ext/libcouchbase/example/crypto/common_provider.c +2 -0
  46. data/ext/libcouchbase/example/crypto/common_provider.h +2 -0
  47. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +5 -0
  48. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +0 -1
  49. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +16 -26
  50. data/ext/libcouchbase/example/db/db.c +10 -6
  51. data/ext/libcouchbase/example/fts/.gitignore +1 -0
  52. data/ext/libcouchbase/example/fts/build-queries.rb +33 -0
  53. data/ext/libcouchbase/example/fts/fts.c +142 -0
  54. data/ext/libcouchbase/example/fts/queries.h +61 -0
  55. data/ext/libcouchbase/example/fts/queries/00-simple-text-query.json +12 -0
  56. data/ext/libcouchbase/example/fts/queries/01-simple-text-query-on-non-default-index.json +9 -0
  57. data/ext/libcouchbase/example/fts/queries/02-simple-text-query-on-stored-field.json +13 -0
  58. data/ext/libcouchbase/example/fts/queries/03-match-query-with-facet.json +19 -0
  59. data/ext/libcouchbase/example/fts/queries/04-docid-query.json +11 -0
  60. data/ext/libcouchbase/example/fts/queries/05-unanalyzed-term-query-with-fuzziness-level-of-0.json +13 -0
  61. data/ext/libcouchbase/example/fts/queries/06-unanalyzed-term-query-with-fuzziness-level-of-2.json +14 -0
  62. data/ext/libcouchbase/example/fts/queries/07-match-phrase-query.json +13 -0
  63. data/ext/libcouchbase/example/fts/queries/08-phrase-query.json +16 -0
  64. data/ext/libcouchbase/example/fts/queries/09-query-string-query.json +9 -0
  65. data/ext/libcouchbase/example/fts/queries/10-conjunction-query.json +21 -0
  66. data/ext/libcouchbase/example/fts/queries/11-wild-card-query.json +13 -0
  67. data/ext/libcouchbase/example/fts/queries/12-numeric-range-query.json +11 -0
  68. data/ext/libcouchbase/example/fts/queries/13-regexp-query.json +13 -0
  69. data/ext/libcouchbase/example/minimal/.gitignore +1 -0
  70. data/ext/libcouchbase/example/minimal/query.c +185 -0
  71. data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +2 -2
  72. data/ext/libcouchbase/example/tracing/cJSON.c +1 -1
  73. data/ext/libcouchbase/example/tracing/cJSON.h +1 -1
  74. data/ext/libcouchbase/include/libcouchbase/cbft.h +38 -4
  75. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +8 -97
  76. data/ext/libcouchbase/include/libcouchbase/cntl.h +288 -8
  77. data/ext/libcouchbase/include/libcouchbase/couchbase.h +47 -10
  78. data/ext/libcouchbase/include/libcouchbase/crypto.h +214 -48
  79. data/ext/libcouchbase/include/libcouchbase/deprecated.h +12 -0
  80. data/ext/libcouchbase/include/libcouchbase/error.h +33 -2
  81. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +1 -1
  82. data/ext/libcouchbase/include/libcouchbase/n1ql.h +87 -13
  83. data/ext/libcouchbase/include/libcouchbase/subdoc.h +3 -7
  84. data/ext/libcouchbase/include/libcouchbase/tracing.h +174 -56
  85. data/ext/libcouchbase/include/libcouchbase/vbucket.h +21 -1
  86. data/ext/libcouchbase/include/libcouchbase/views.h +49 -4
  87. data/ext/libcouchbase/packaging/deb/control +2 -3
  88. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  89. data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +7 -5
  90. data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +7 -5
  91. data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +14 -12
  92. data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +3 -0
  93. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +14 -6
  94. data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +7 -5
  95. data/ext/libcouchbase/src/bootstrap.cc +6 -1
  96. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +2 -7
  97. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +1 -1
  98. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +4 -11
  99. data/ext/libcouchbase/src/bucketconfig/clconfig.h +29 -36
  100. data/ext/libcouchbase/src/bucketconfig/confmon.cc +4 -2
  101. data/ext/libcouchbase/src/cntl.cc +181 -151
  102. data/ext/libcouchbase/src/config_static.h +1 -1
  103. data/ext/libcouchbase/src/connspec.cc +5 -1
  104. data/ext/libcouchbase/src/connspec.h +3 -1
  105. data/ext/libcouchbase/src/crypto.cc +93 -80
  106. data/ext/libcouchbase/src/dns-srv.cc +1 -1
  107. data/ext/libcouchbase/src/handler.cc +0 -1
  108. data/ext/libcouchbase/src/http/http-priv.h +1 -0
  109. data/ext/libcouchbase/src/http/http.cc +1 -2
  110. data/ext/libcouchbase/src/instance.cc +21 -2
  111. data/ext/libcouchbase/src/internal.h +1 -0
  112. data/ext/libcouchbase/src/lcbio/ctx.c +24 -3
  113. data/ext/libcouchbase/src/lcbio/ioutils.cc +1 -1
  114. data/ext/libcouchbase/src/lcbio/rw-inl.h +22 -1
  115. data/ext/libcouchbase/src/lcbio/ssl.h +2 -0
  116. data/ext/libcouchbase/src/mc/compress.cc +18 -11
  117. data/ext/libcouchbase/src/mc/mcreq.c +2 -0
  118. data/ext/libcouchbase/src/mc/mcreq.h +1 -1
  119. data/ext/libcouchbase/src/mcserver/mcserver.cc +163 -6
  120. data/ext/libcouchbase/src/mcserver/negotiate.cc +17 -7
  121. data/ext/libcouchbase/src/n1ql/n1ql.cc +12 -3
  122. data/ext/libcouchbase/src/newconfig.cc +4 -3
  123. data/ext/libcouchbase/src/nodeinfo.cc +1 -7
  124. data/ext/libcouchbase/src/operations/observe.cc +1 -0
  125. data/ext/libcouchbase/src/operations/ping.cc +5 -3
  126. data/ext/libcouchbase/src/retryq.cc +22 -0
  127. data/ext/libcouchbase/src/retryq.h +2 -1
  128. data/ext/libcouchbase/src/rnd.cc +5 -12
  129. data/ext/libcouchbase/src/settings.c +4 -7
  130. data/ext/libcouchbase/src/settings.h +6 -2
  131. data/ext/libcouchbase/src/strcodecs/base64.c +59 -0
  132. data/ext/libcouchbase/src/strcodecs/strcodecs.h +2 -0
  133. data/ext/libcouchbase/src/trace.h +2 -2
  134. data/ext/libcouchbase/src/tracing/span.cc +177 -45
  135. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +70 -28
  136. data/ext/libcouchbase/src/tracing/tracing-internal.h +33 -48
  137. data/ext/libcouchbase/src/vbucket/vbucket.c +146 -30
  138. data/ext/libcouchbase/src/wait.cc +1 -1
  139. data/ext/libcouchbase/tests/CMakeLists.txt +13 -4
  140. data/ext/libcouchbase/tests/iotests/mock-environment.cc +1 -1
  141. data/ext/libcouchbase/tests/iotests/t_misc.cc +2 -2
  142. data/ext/libcouchbase/tests/iotests/t_views.cc +1 -1
  143. data/ext/libcouchbase/tests/iotests/testutil.cc +3 -2
  144. data/ext/libcouchbase/tests/vbucket/confdata/map_node_present_nodesext_missing_nodes.json +94 -0
  145. data/ext/libcouchbase/tests/vbucket/t_config.cc +15 -0
  146. data/ext/libcouchbase/tools/CMakeLists.txt +11 -6
  147. data/ext/libcouchbase/tools/cbc-handlers.h +9 -0
  148. data/ext/libcouchbase/tools/cbc-proxy.cc +1 -1
  149. data/ext/libcouchbase/tools/cbc.cc +33 -5
  150. data/ext/libcouchbase/tools/common/options.cc +1 -1
  151. data/ext/libcouchbase/tools/extract-packets.rb +110 -0
  152. data/lib/libcouchbase/connection.rb +13 -5
  153. data/lib/libcouchbase/ext/tasks.rb +1 -1
  154. data/lib/libcouchbase/version.rb +1 -1
  155. metadata +62 -7
@@ -247,9 +247,11 @@ void Confmon::do_next_provider()
247
247
  state &= ~CONFMON_S_ITERGRACE;
248
248
  for (ProviderList::const_iterator ii = active_providers.begin();
249
249
  ii != active_providers.end(); ++ii) {
250
- ConfigInfo *info;
251
250
  Provider* cached_provider = *ii;
252
- info = cached_provider->get_cached();
251
+ if (!cached_provider) {
252
+ continue;
253
+ }
254
+ ConfigInfo *info = cached_provider->get_cached();
253
255
  if (!info) {
254
256
  continue;
255
257
  }
@@ -165,6 +165,9 @@ HANDLER(retry_backoff_handler) {
165
165
  HANDLER(http_poolsz_handler) {
166
166
  RETURN_GET_SET(lcb_SIZE, instance->http_sockpool->get_options().maxidle)
167
167
  }
168
+ HANDLER(http_pooltmo_handler) {
169
+ RETURN_GET_SET(uint32_t, instance->http_sockpool->get_options().tmoidle)
170
+ }
168
171
  HANDLER(http_refresh_config_handler) {
169
172
  RETURN_GET_SET(int, LCBT_SETTING(instance, refresh_on_hterr))
170
173
  }
@@ -186,6 +189,9 @@ HANDLER(vbguess_handler) {
186
189
  HANDLER(vb_noremap_handler) {
187
190
  RETURN_GET_SET(int, LCBT_SETTING(instance, vb_noremap))
188
191
  }
192
+ HANDLER(wait_for_config_handler) {
193
+ RETURN_GET_SET(int, LCBT_SETTING(instance, wait_for_config))
194
+ }
189
195
  HANDLER(fetch_mutation_tokens_handler) {
190
196
  RETURN_GET_SET(int, LCBT_SETTING(instance, fetch_mutation_tokens))
191
197
  }
@@ -508,6 +514,7 @@ HANDLER(client_string_handler) {
508
514
  if (mode == LCB_CNTL_SET) {
509
515
  const char *val = reinterpret_cast<const char*>(arg);
510
516
  free(LCBT_SETTING(instance, client_string));
517
+ LCBT_SETTING(instance, client_string) = NULL;
511
518
  if (val) {
512
519
  LCBT_SETTING(instance, client_string) = strdup(val);
513
520
  }
@@ -641,98 +648,116 @@ HANDLER(comp_min_ratio_handler) {
641
648
  RETURN_GET_SET(float, LCBT_SETTING(instance, compress_min_ratio))
642
649
  }
643
650
 
651
+ HANDLER(network_handler) {
652
+ if (mode == LCB_CNTL_SET) {
653
+ const char *val = reinterpret_cast<const char*>(arg);
654
+ free(LCBT_SETTING(instance, network));
655
+ LCBT_SETTING(instance, network) = NULL;
656
+ if (val) {
657
+ LCBT_SETTING(instance, network) = strdup(val);
658
+ }
659
+ } else {
660
+ *(const char **)arg = LCBT_SETTING(instance, network);
661
+ }
662
+ (void)cmd;
663
+ return LCB_SUCCESS;
664
+ }
665
+
644
666
  static ctl_handler handlers[] = {
645
- timeout_common, /* LCB_CNTL_OP_TIMEOUT */
646
- timeout_common, /* LCB_CNTL_VIEW_TIMEOUT */
647
- noop_handler, /* LCB_CNTL_RBUFSIZE */
648
- noop_handler, /* LCB_CNTL_WBUFSIZE */
649
- get_htype, /* LCB_CNTL_HANDLETYPE */
650
- get_vbconfig, /* LCB_CNTL_VBCONFIG */
651
- get_iops, /* LCB_CNTL_IOPS */
652
- get_kvb, /* LCB_CNTL_VBMAP */
653
- conninfo, /* LCB_CNTL_MEMDNODE_INFO */
654
- conninfo, /* LCB_CNTL_CONFIGNODE_INFO */
655
- syncmode, /* LCB_CNTL_SYNCMODE */
656
- ippolicy, /* LCB_CNTL_IP6POLICY */
657
- confthresh /* LCB_CNTL_CONFERRTHRESH */,
658
- timeout_common, /* LCB_CNTL_DURABILITY_INTERVAL */
659
- timeout_common, /* LCB_CNTL_DURABILITY_TIMEOUT */
660
- timeout_common, /* LCB_CNTL_HTTP_TIMEOUT */
661
- lcb_iops_cntl_handler, /* LCB_CNTL_IOPS_DEFAULT_TYPES */
662
- lcb_iops_cntl_handler, /* LCB_CNTL_IOPS_DLOPEN_DEBUG */
663
- timeout_common, /* LCB_CNTL_CONFIGURATION_TIMEOUT */
664
- noop_handler, /* LCB_CNTL_SKIP_CONFIGURATION_ERRORS_ON_CONNECT */
665
- randomize_bootstrap_hosts_handler /* LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS */,
666
- config_cache_loaded_handler /* LCB_CNTL_CONFIG_CACHE_LOADED */,
667
- force_sasl_mech_handler, /* LCB_CNTL_FORCE_SASL_MECH */
668
- max_redirects, /* LCB_CNTL_MAX_REDIRECTS */
669
- logprocs_handler /* LCB_CNTL_LOGGER */,
670
- timeout_common, /* LCB_CNTL_CONFDELAY_THRESH */
671
- config_transport, /* LCB_CNTL_CONFIG_TRANSPORT */
672
- timeout_common, /* LCB_CNTL_CONFIG_NODE_TIMEOUT */
673
- timeout_common, /* LCB_CNTL_HTCONFIG_IDLE_TIMEOUT */
674
- config_nodes, /* LCB_CNTL_CONFIG_HTTP_NODES */
675
- config_nodes, /* LCB_CNTL_CONFIG_CCCP_NODES */
676
- get_changeset, /* LCB_CNTL_CHANGESET */
677
- init_providers, /* LCB_CNTL_CONFIG_ALL_NODES */
678
- config_cache_handler, /* LCB_CNTL_CONFIGCACHE */
679
- ssl_mode_handler, /* LCB_CNTL_SSL_MODE */
680
- ssl_certpath_handler, /* LCB_CNTL_SSL_CERT */
681
- retrymode_handler, /* LCB_CNTL_RETRYMODE */
682
- htconfig_urltype_handler, /* LCB_CNTL_HTCONFIG_URLTYPE */
683
- compmode_handler, /* LCB_CNTL_COMPRESSION_OPTS */
684
- allocfactory_handler, /* LCB_CNTL_RDBALLOCFACTORY */
685
- syncdtor_handler, /* LCB_CNTL_SYNCDESTROY */
686
- console_log_handler, /* LCB_CNTL_CONLOGGER_LEVEL */
687
- detailed_errcode_handler, /* LCB_CNTL_DETAILED_ERRCODES */
688
- reinit_spec_handler, /* LCB_CNTL_REINIT_CONNSTR */
689
- timeout_common, /* LCB_CNTL_RETRY_INTERVAL */
690
- retry_backoff_handler, /* LCB_CNTL_RETRY_BACKOFF */
691
- http_poolsz_handler, /* LCB_CNTL_HTTP_POOLSIZE */
692
- http_refresh_config_handler, /* LCB_CNTL_HTTP_REFRESH_CONFIG_ON_ERROR */
693
- bucketname_handler, /* LCB_CNTL_BUCKETNAME */
694
- schedflush_handler, /* LCB_CNTL_SCHED_IMPLICIT_FLUSH */
695
- vbguess_handler, /* LCB_CNTL_VBGUESS_PERSIST */
696
- unsafe_optimize, /* LCB_CNTL_UNSAFE_OPTIMIZE */
697
- fetch_mutation_tokens_handler, /* LCB_CNTL_FETCH_MUTATION_TOKENS */
698
- dur_mutation_tokens_handler, /* LCB_CNTL_DURABILITY_MUTATION_TOKENS */
699
- config_cache_handler, /* LCB_CNTL_CONFIGCACHE_READONLY */
700
- nmv_imm_retry_handler, /* LCB_CNTL_RETRY_NMV_IMM */
701
- mutation_tokens_supported_handler, /* LCB_CNTL_MUTATION_TOKENS_SUPPORTED */
702
- tcp_nodelay_handler, /* LCB_CNTL_TCP_NODELAY */
703
- readj_ts_wait_handler, /* LCB_CNTL_RESET_TIMEOUT_ON_WAIT */
704
- console_fp_handler, /* LCB_CNTL_CONLOGGER_FP */
705
- kv_hg_handler, /* LCB_CNTL_KVTIMINGS */
706
- timeout_common, /* LCB_CNTL_N1QL_TIMEOUT */
707
- n1ql_cache_clear_handler, /* LCB_CNTL_N1QL_CLEARCACHE */
708
- client_string_handler, /* LCB_CNTL_CLIENT_STRING */
709
- bucket_auth_handler, /* LCB_CNTL_BUCKET_CRED */
710
- timeout_common, /* LCB_CNTL_RETRY_NMV_DELAY */
711
- read_chunk_size_handler, /*LCB_CNTL_READ_CHUNKSIZE */
712
- enable_errmap_handler, /* LCB_CNTL_ENABLE_ERRMAP */
713
- select_bucket_handler, /* LCB_CNTL_SELECT_BUCKET */
714
- tcp_keepalive_handler, /* LCB_CNTL_TCP_KEEPALIVE */
715
- config_poll_interval_handler, /* LCB_CNTL_CONFIG_POLL_INTERVAL */
716
- send_hello_handler, /* LCB_CNTL_SEND_HELLO */
717
- buckettype_handler, /* LCB_CNTL_BUCKETTYPE */
718
- metrics_handler, /* LCB_CNTL_METRICS */
719
- collections_handler, /* LCB_CNTL_USE_COLLECTIONS */
720
- ssl_keypath_handler, /* LCB_CNTL_SSL_KEY */
721
- log_redaction_handler, /* LCB_CNTL_LOG_REDACTION */
722
- ssl_truststorepath_handler, /* LCB_CNTL_SSL_TRUSTSTORE */
723
- enable_tracing_handler, /* LCB_CNTL_ENABLE_TRACING */
724
- timeout_common, /* LCB_CNTL_TRACING_ORPHANED_QUEUE_FLUSH_INTERVAL */
725
- tracing_orphaned_queue_size_handler, /* LCB_CNTL_TRACING_ORPHANED_QUEUE_SIZE */
726
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_QUEUE_FLUSH_INTERVAL */
667
+ timeout_common, /* LCB_CNTL_OP_TIMEOUT */
668
+ timeout_common, /* LCB_CNTL_VIEW_TIMEOUT */
669
+ noop_handler, /* LCB_CNTL_RBUFSIZE */
670
+ noop_handler, /* LCB_CNTL_WBUFSIZE */
671
+ get_htype, /* LCB_CNTL_HANDLETYPE */
672
+ get_vbconfig, /* LCB_CNTL_VBCONFIG */
673
+ get_iops, /* LCB_CNTL_IOPS */
674
+ get_kvb, /* LCB_CNTL_VBMAP */
675
+ conninfo, /* LCB_CNTL_MEMDNODE_INFO */
676
+ conninfo, /* LCB_CNTL_CONFIGNODE_INFO */
677
+ syncmode, /* LCB_CNTL_SYNCMODE */
678
+ ippolicy, /* LCB_CNTL_IP6POLICY */
679
+ confthresh, /* LCB_CNTL_CONFERRTHRESH */
680
+ timeout_common, /* LCB_CNTL_DURABILITY_INTERVAL */
681
+ timeout_common, /* LCB_CNTL_DURABILITY_TIMEOUT */
682
+ timeout_common, /* LCB_CNTL_HTTP_TIMEOUT */
683
+ lcb_iops_cntl_handler, /* LCB_CNTL_IOPS_DEFAULT_TYPES */
684
+ lcb_iops_cntl_handler, /* LCB_CNTL_IOPS_DLOPEN_DEBUG */
685
+ timeout_common, /* LCB_CNTL_CONFIGURATION_TIMEOUT */
686
+ noop_handler, /* LCB_CNTL_SKIP_CONFIGURATION_ERRORS_ON_CONNECT */
687
+ randomize_bootstrap_hosts_handler, /* LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS */
688
+ config_cache_loaded_handler, /* LCB_CNTL_CONFIG_CACHE_LOADED */
689
+ force_sasl_mech_handler, /* LCB_CNTL_FORCE_SASL_MECH */
690
+ max_redirects, /* LCB_CNTL_MAX_REDIRECTS */
691
+ logprocs_handler, /* LCB_CNTL_LOGGER */
692
+ timeout_common, /* LCB_CNTL_CONFDELAY_THRESH */
693
+ config_transport, /* LCB_CNTL_CONFIG_TRANSPORT */
694
+ timeout_common, /* LCB_CNTL_CONFIG_NODE_TIMEOUT */
695
+ timeout_common, /* LCB_CNTL_HTCONFIG_IDLE_TIMEOUT */
696
+ config_nodes, /* LCB_CNTL_CONFIG_HTTP_NODES */
697
+ config_nodes, /* LCB_CNTL_CONFIG_CCCP_NODES */
698
+ get_changeset, /* LCB_CNTL_CHANGESET */
699
+ init_providers, /* LCB_CNTL_CONFIG_ALL_NODES */
700
+ config_cache_handler, /* LCB_CNTL_CONFIGCACHE */
701
+ ssl_mode_handler, /* LCB_CNTL_SSL_MODE */
702
+ ssl_certpath_handler, /* LCB_CNTL_SSL_CERT */
703
+ retrymode_handler, /* LCB_CNTL_RETRYMODE */
704
+ htconfig_urltype_handler, /* LCB_CNTL_HTCONFIG_URLTYPE */
705
+ compmode_handler, /* LCB_CNTL_COMPRESSION_OPTS */
706
+ allocfactory_handler, /* LCB_CNTL_RDBALLOCFACTORY */
707
+ syncdtor_handler, /* LCB_CNTL_SYNCDESTROY */
708
+ console_log_handler, /* LCB_CNTL_CONLOGGER_LEVEL */
709
+ detailed_errcode_handler, /* LCB_CNTL_DETAILED_ERRCODES */
710
+ reinit_spec_handler, /* LCB_CNTL_REINIT_CONNSTR */
711
+ timeout_common, /* LCB_CNTL_RETRY_INTERVAL */
712
+ retry_backoff_handler, /* LCB_CNTL_RETRY_BACKOFF */
713
+ http_poolsz_handler, /* LCB_CNTL_HTTP_POOLSIZE */
714
+ http_refresh_config_handler, /* LCB_CNTL_HTTP_REFRESH_CONFIG_ON_ERROR */
715
+ bucketname_handler, /* LCB_CNTL_BUCKETNAME */
716
+ schedflush_handler, /* LCB_CNTL_SCHED_IMPLICIT_FLUSH */
717
+ vbguess_handler, /* LCB_CNTL_VBGUESS_PERSIST */
718
+ unsafe_optimize, /* LCB_CNTL_UNSAFE_OPTIMIZE */
719
+ fetch_mutation_tokens_handler, /* LCB_CNTL_FETCH_MUTATION_TOKENS */
720
+ dur_mutation_tokens_handler, /* LCB_CNTL_DURABILITY_MUTATION_TOKENS */
721
+ config_cache_handler, /* LCB_CNTL_CONFIGCACHE_READONLY */
722
+ nmv_imm_retry_handler, /* LCB_CNTL_RETRY_NMV_IMM */
723
+ mutation_tokens_supported_handler, /* LCB_CNTL_MUTATION_TOKENS_SUPPORTED */
724
+ tcp_nodelay_handler, /* LCB_CNTL_TCP_NODELAY */
725
+ readj_ts_wait_handler, /* LCB_CNTL_RESET_TIMEOUT_ON_WAIT */
726
+ console_fp_handler, /* LCB_CNTL_CONLOGGER_FP */
727
+ kv_hg_handler, /* LCB_CNTL_KVTIMINGS */
728
+ timeout_common, /* LCB_CNTL_N1QL_TIMEOUT */
729
+ n1ql_cache_clear_handler, /* LCB_CNTL_N1QL_CLEARCACHE */
730
+ client_string_handler, /* LCB_CNTL_CLIENT_STRING */
731
+ bucket_auth_handler, /* LCB_CNTL_BUCKET_CRED */
732
+ timeout_common, /* LCB_CNTL_RETRY_NMV_DELAY */
733
+ read_chunk_size_handler, /* LCB_CNTL_READ_CHUNKSIZE */
734
+ enable_errmap_handler, /* LCB_CNTL_ENABLE_ERRMAP */
735
+ select_bucket_handler, /* LCB_CNTL_SELECT_BUCKET */
736
+ tcp_keepalive_handler, /* LCB_CNTL_TCP_KEEPALIVE */
737
+ config_poll_interval_handler, /* LCB_CNTL_CONFIG_POLL_INTERVAL */
738
+ send_hello_handler, /* LCB_CNTL_SEND_HELLO */
739
+ buckettype_handler, /* LCB_CNTL_BUCKETTYPE */
740
+ metrics_handler, /* LCB_CNTL_METRICS */
741
+ collections_handler, /* LCB_CNTL_USE_COLLECTIONS */
742
+ ssl_keypath_handler, /* LCB_CNTL_SSL_KEY */
743
+ log_redaction_handler, /* LCB_CNTL_LOG_REDACTION */
744
+ ssl_truststorepath_handler, /* LCB_CNTL_SSL_TRUSTSTORE */
745
+ enable_tracing_handler, /* LCB_CNTL_ENABLE_TRACING */
746
+ timeout_common, /* LCB_CNTL_TRACING_ORPHANED_QUEUE_FLUSH_INTERVAL */
747
+ tracing_orphaned_queue_size_handler, /* LCB_CNTL_TRACING_ORPHANED_QUEUE_SIZE */
748
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_QUEUE_FLUSH_INTERVAL */
727
749
  tracing_threshold_queue_size_handler, /* LCB_CNTL_TRACING_THRESHOLD_QUEUE_SIZE */
728
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_KV */
729
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_N1QL */
730
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_VIEW */
731
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_FTS */
732
- timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_ANALYTICS */
733
- comp_min_size_handler, /* LCB_CNTL_COMPRESSION_MIN_SIZE */
734
- comp_min_ratio_handler, /* LCB_CNTL_COMPRESSION_MIN_RATIO */
735
- vb_noremap_handler, /* LCB_CNTL_VB_NOREMAP */
750
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_KV */
751
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_N1QL */
752
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_VIEW */
753
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_FTS */
754
+ timeout_common, /* LCB_CNTL_TRACING_THRESHOLD_ANALYTICS */
755
+ comp_min_size_handler, /* LCB_CNTL_COMPRESSION_MIN_SIZE */
756
+ comp_min_ratio_handler, /* LCB_CNTL_COMPRESSION_MIN_RATIO */
757
+ vb_noremap_handler, /* LCB_CNTL_VB_NOREMAP */
758
+ network_handler, /* LCB_CNTL_NETWORK */
759
+ wait_for_config_handler, /* LCB_CNTL_WAIT_FOR_CONFIG */
760
+ http_pooltmo_handler /* LCB_CNTL_HTTP_POOL_TIMEOUT */
736
761
  };
737
762
 
738
763
  /* Union used for conversion to/from string functions */
@@ -791,7 +816,10 @@ static lcb_error_t convert_int(const char *arg, u_STRCONVERT *u) {
791
816
  }
792
817
 
793
818
  static lcb_error_t convert_u32(const char *arg, u_STRCONVERT *u) {
794
- return convert_timevalue(arg, u);
819
+ unsigned int tmp;
820
+ int rv = sscanf(arg, "%u", &tmp);
821
+ u->u32 = tmp;
822
+ return rv == 1 ? LCB_SUCCESS : LCB_ECTL_BADARG;
795
823
  }
796
824
  static lcb_error_t convert_float(const char *arg, u_STRCONVERT *u) {
797
825
  double d;
@@ -860,66 +888,68 @@ static lcb_error_t convert_ipv6(const char *arg, u_STRCONVERT *u)
860
888
  }
861
889
 
862
890
  static cntl_OPCODESTRS stropcode_map[] = {
863
- {"operation_timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
864
- {"timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
865
- {"views_timeout", LCB_CNTL_VIEW_TIMEOUT, convert_timevalue},
866
- {"n1ql_timeout", LCB_CNTL_N1QL_TIMEOUT, convert_timevalue},
867
- {"durability_timeout", LCB_CNTL_DURABILITY_TIMEOUT, convert_timevalue},
868
- {"durability_interval", LCB_CNTL_DURABILITY_INTERVAL, convert_timevalue},
869
- {"http_timeout", LCB_CNTL_HTTP_TIMEOUT, convert_timevalue},
870
- {"randomize_nodes", LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS, convert_intbool},
871
- {"sasl_mech_force", LCB_CNTL_FORCE_SASL_MECH, convert_passthru},
872
- {"error_thresh_count", LCB_CNTL_CONFERRTHRESH, convert_SIZE},
873
- {"error_thresh_delay", LCB_CNTL_CONFDELAY_THRESH, convert_timevalue},
874
- {"config_total_timeout", LCB_CNTL_CONFIGURATION_TIMEOUT, convert_timevalue},
875
- {"config_node_timeout", LCB_CNTL_CONFIG_NODE_TIMEOUT, convert_timevalue},
876
- {"compression", LCB_CNTL_COMPRESSION_OPTS, convert_compression},
877
- {"console_log_level", LCB_CNTL_CONLOGGER_LEVEL, convert_u32},
878
- {"config_cache", LCB_CNTL_CONFIGCACHE, convert_passthru },
879
- {"config_cache_ro", LCB_CNTL_CONFIGCACHE_RO, convert_passthru },
880
- {"detailed_errcodes", LCB_CNTL_DETAILED_ERRCODES, convert_intbool},
881
- {"retry_policy", LCB_CNTL_RETRYMODE, convert_retrymode},
882
- {"http_urlmode", LCB_CNTL_HTCONFIG_URLTYPE, convert_int },
883
- {"sync_dtor", LCB_CNTL_SYNCDESTROY, convert_intbool },
884
- {"_reinit_connstr", LCB_CNTL_REINIT_CONNSTR },
885
- {"retry_backoff", LCB_CNTL_RETRY_BACKOFF, convert_float },
886
- {"retry_interval", LCB_CNTL_RETRY_INTERVAL, convert_timevalue},
887
- {"http_poolsize", LCB_CNTL_HTTP_POOLSIZE, convert_SIZE },
888
- {"vbguess_persist", LCB_CNTL_VBGUESS_PERSIST, convert_intbool },
889
- {"unsafe_optimize", LCB_CNTL_UNSAFE_OPTIMIZE, convert_intbool },
890
- {"fetch_mutation_tokens", LCB_CNTL_FETCH_MUTATION_TOKENS, convert_intbool },
891
- {"dur_mutation_tokens", LCB_CNTL_DURABILITY_MUTATION_TOKENS, convert_intbool },
892
- {"retry_nmv_imm", LCB_CNTL_RETRY_NMV_IMM, convert_intbool },
893
- {"tcp_nodelay", LCB_CNTL_TCP_NODELAY, convert_intbool },
894
- {"readj_ts_wait", LCB_CNTL_RESET_TIMEOUT_ON_WAIT, convert_intbool },
895
- {"console_log_file", LCB_CNTL_CONLOGGER_FP, NULL },
896
- {"client_string", LCB_CNTL_CLIENT_STRING, convert_passthru},
897
- {"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timevalue},
898
- {"bucket_cred", LCB_CNTL_BUCKET_CRED, NULL},
899
- {"read_chunk_size", LCB_CNTL_READ_CHUNKSIZE, convert_u32},
900
- {"enable_errmap", LCB_CNTL_ENABLE_ERRMAP, convert_intbool},
901
- {"select_bucket", LCB_CNTL_SELECT_BUCKET, convert_intbool},
902
- {"tcp_keepalive", LCB_CNTL_TCP_KEEPALIVE, convert_intbool},
903
- {"config_poll_interval", LCB_CNTL_CONFIG_POLL_INTERVAL, convert_timevalue},
904
- {"send_hello", LCB_CNTL_SEND_HELLO, convert_intbool},
905
- {"ipv6", LCB_CNTL_IP6POLICY, convert_ipv6},
906
- {"metrics", LCB_CNTL_METRICS, convert_intbool },
907
- {"log_redaction", LCB_CNTL_LOG_REDACTION, convert_intbool},
908
- {"enable_tracing", LCB_CNTL_ENABLE_TRACING, convert_intbool},
909
- {"tracing_orphaned_queue_flush_interval", LCB_CNTL_TRACING_ORPHANED_QUEUE_FLUSH_INTERVAL, convert_timevalue},
910
- {"tracing_orphaned_queue_size", LCB_CNTL_TRACING_ORPHANED_QUEUE_SIZE, convert_u32},
911
- {"tracing_threshold_queue_flush_interval", LCB_CNTL_TRACING_THRESHOLD_QUEUE_FLUSH_INTERVAL, convert_timevalue},
912
- {"tracing_threshold_queue_size", LCB_CNTL_TRACING_THRESHOLD_QUEUE_SIZE, convert_u32},
913
- {"tracing_threshold_kv", LCB_CNTL_TRACING_THRESHOLD_KV, convert_timevalue},
914
- {"tracing_threshold_n1ql", LCB_CNTL_TRACING_THRESHOLD_N1QL, convert_timevalue},
915
- {"tracing_threshold_view", LCB_CNTL_TRACING_THRESHOLD_VIEW, convert_timevalue},
916
- {"tracing_threshold_fts", LCB_CNTL_TRACING_THRESHOLD_FTS, convert_timevalue},
917
- {"tracing_threshold_analytics", LCB_CNTL_TRACING_THRESHOLD_ANALYTICS, convert_timevalue},
918
- {"compression_min_size", LCB_CNTL_COMPRESSION_MIN_SIZE, convert_u32},
919
- {"compression_min_ratio", LCB_CNTL_COMPRESSION_MIN_RATIO, convert_float},
920
- {"vb_noremap", LCB_CNTL_VB_NOREMAP, convert_intbool },
921
- {NULL, -1}
922
- };
891
+ {"operation_timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
892
+ {"timeout", LCB_CNTL_OP_TIMEOUT, convert_timevalue},
893
+ {"views_timeout", LCB_CNTL_VIEW_TIMEOUT, convert_timevalue},
894
+ {"n1ql_timeout", LCB_CNTL_N1QL_TIMEOUT, convert_timevalue},
895
+ {"durability_timeout", LCB_CNTL_DURABILITY_TIMEOUT, convert_timevalue},
896
+ {"durability_interval", LCB_CNTL_DURABILITY_INTERVAL, convert_timevalue},
897
+ {"http_timeout", LCB_CNTL_HTTP_TIMEOUT, convert_timevalue},
898
+ {"randomize_nodes", LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS, convert_intbool},
899
+ {"sasl_mech_force", LCB_CNTL_FORCE_SASL_MECH, convert_passthru},
900
+ {"error_thresh_count", LCB_CNTL_CONFERRTHRESH, convert_SIZE},
901
+ {"error_thresh_delay", LCB_CNTL_CONFDELAY_THRESH, convert_timevalue},
902
+ {"config_total_timeout", LCB_CNTL_CONFIGURATION_TIMEOUT, convert_timevalue},
903
+ {"config_node_timeout", LCB_CNTL_CONFIG_NODE_TIMEOUT, convert_timevalue},
904
+ {"compression", LCB_CNTL_COMPRESSION_OPTS, convert_compression},
905
+ {"console_log_level", LCB_CNTL_CONLOGGER_LEVEL, convert_u32},
906
+ {"config_cache", LCB_CNTL_CONFIGCACHE, convert_passthru},
907
+ {"config_cache_ro", LCB_CNTL_CONFIGCACHE_RO, convert_passthru},
908
+ {"detailed_errcodes", LCB_CNTL_DETAILED_ERRCODES, convert_intbool},
909
+ {"retry_policy", LCB_CNTL_RETRYMODE, convert_retrymode},
910
+ {"http_urlmode", LCB_CNTL_HTCONFIG_URLTYPE, convert_int},
911
+ {"sync_dtor", LCB_CNTL_SYNCDESTROY, convert_intbool},
912
+ {"_reinit_connstr", LCB_CNTL_REINIT_CONNSTR},
913
+ {"retry_backoff", LCB_CNTL_RETRY_BACKOFF, convert_float},
914
+ {"retry_interval", LCB_CNTL_RETRY_INTERVAL, convert_timevalue},
915
+ {"http_poolsize", LCB_CNTL_HTTP_POOLSIZE, convert_SIZE},
916
+ {"vbguess_persist", LCB_CNTL_VBGUESS_PERSIST, convert_intbool},
917
+ {"unsafe_optimize", LCB_CNTL_UNSAFE_OPTIMIZE, convert_intbool},
918
+ {"fetch_mutation_tokens", LCB_CNTL_FETCH_MUTATION_TOKENS, convert_intbool},
919
+ {"dur_mutation_tokens", LCB_CNTL_DURABILITY_MUTATION_TOKENS, convert_intbool},
920
+ {"retry_nmv_imm", LCB_CNTL_RETRY_NMV_IMM, convert_intbool},
921
+ {"tcp_nodelay", LCB_CNTL_TCP_NODELAY, convert_intbool},
922
+ {"readj_ts_wait", LCB_CNTL_RESET_TIMEOUT_ON_WAIT, convert_intbool},
923
+ {"console_log_file", LCB_CNTL_CONLOGGER_FP, NULL},
924
+ {"client_string", LCB_CNTL_CLIENT_STRING, convert_passthru},
925
+ {"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timevalue},
926
+ {"bucket_cred", LCB_CNTL_BUCKET_CRED, NULL},
927
+ {"read_chunk_size", LCB_CNTL_READ_CHUNKSIZE, convert_u32},
928
+ {"enable_errmap", LCB_CNTL_ENABLE_ERRMAP, convert_intbool},
929
+ {"select_bucket", LCB_CNTL_SELECT_BUCKET, convert_intbool},
930
+ {"tcp_keepalive", LCB_CNTL_TCP_KEEPALIVE, convert_intbool},
931
+ {"config_poll_interval", LCB_CNTL_CONFIG_POLL_INTERVAL, convert_timevalue},
932
+ {"send_hello", LCB_CNTL_SEND_HELLO, convert_intbool},
933
+ {"ipv6", LCB_CNTL_IP6POLICY, convert_ipv6},
934
+ {"metrics", LCB_CNTL_METRICS, convert_intbool},
935
+ {"log_redaction", LCB_CNTL_LOG_REDACTION, convert_intbool},
936
+ {"enable_tracing", LCB_CNTL_ENABLE_TRACING, convert_intbool},
937
+ {"tracing_orphaned_queue_flush_interval", LCB_CNTL_TRACING_ORPHANED_QUEUE_FLUSH_INTERVAL, convert_timevalue},
938
+ {"tracing_orphaned_queue_size", LCB_CNTL_TRACING_ORPHANED_QUEUE_SIZE, convert_u32},
939
+ {"tracing_threshold_queue_flush_interval", LCB_CNTL_TRACING_THRESHOLD_QUEUE_FLUSH_INTERVAL, convert_timevalue},
940
+ {"tracing_threshold_queue_size", LCB_CNTL_TRACING_THRESHOLD_QUEUE_SIZE, convert_u32},
941
+ {"tracing_threshold_kv", LCB_CNTL_TRACING_THRESHOLD_KV, convert_timevalue},
942
+ {"tracing_threshold_n1ql", LCB_CNTL_TRACING_THRESHOLD_N1QL, convert_timevalue},
943
+ {"tracing_threshold_view", LCB_CNTL_TRACING_THRESHOLD_VIEW, convert_timevalue},
944
+ {"tracing_threshold_fts", LCB_CNTL_TRACING_THRESHOLD_FTS, convert_timevalue},
945
+ {"tracing_threshold_analytics", LCB_CNTL_TRACING_THRESHOLD_ANALYTICS, convert_timevalue},
946
+ {"compression_min_size", LCB_CNTL_COMPRESSION_MIN_SIZE, convert_u32},
947
+ {"compression_min_ratio", LCB_CNTL_COMPRESSION_MIN_RATIO, convert_float},
948
+ {"vb_noremap", LCB_CNTL_VB_NOREMAP, convert_intbool},
949
+ {"network", LCB_CNTL_NETWORK, convert_passthru},
950
+ {"wait_for_config", LCB_CNTL_WAIT_FOR_CONFIG, convert_intbool},
951
+ {"http_pool_timeout", LCB_CNTL_HTTP_POOL_TIMEOUT, convert_timevalue},
952
+ {NULL, -1}};
923
953
 
924
954
  #define CNTL_NUM_HANDLERS (sizeof(handlers) / sizeof(handlers[0]))
925
955
 
@@ -47,7 +47,7 @@
47
47
  #define __STDC_FORMAT_MACROS 1
48
48
  #endif
49
49
  #include <inttypes.h>
50
- #elif defined(_MSC_VER)
50
+ #elif defined(_WIN32)
51
51
  #ifndef PRIx64
52
52
  #define PRIx64 "I64x"
53
53
  #endif
@@ -496,7 +496,11 @@ Connspec::load(const lcb_create_st& cropts)
496
496
  m_password = cr2->passwd;
497
497
  }
498
498
 
499
- if (cropts.version == 3) {
499
+ if (cropts.version == 4) {
500
+ m_logger = cropts.v.v4.logger;
501
+ }
502
+
503
+ if (cropts.version == 3 || cropts.version == 4) {
500
504
  return parse(cropts.v.v3.connstr, &errmsg);
501
505
  }
502
506
 
@@ -61,7 +61,7 @@ struct Spechost {
61
61
  class LCB_CLASS_EXPORT Connspec {
62
62
  public:
63
63
  typedef std::vector<std::pair<std::string,std::string> > Options;
64
- Connspec() : m_sslopts(0), m_implicit_port(0), m_loglevel(0), m_logredact(false), m_flags(0), m_ipv6(LCB_IPV6_DISABLED) {}
64
+ Connspec() : m_sslopts(0), m_implicit_port(0), m_loglevel(0), m_logredact(false), m_transports(), m_flags(0), m_ipv6(LCB_IPV6_DISABLED), m_logger(NULL) {}
65
65
 
66
66
  lcb_error_t parse(const char *connstr, const char **errmsg = NULL);
67
67
  lcb_error_t load(const lcb_create_st&);
@@ -97,6 +97,7 @@ public:
97
97
  const std::string& keypath() const { return m_keypath; }
98
98
  unsigned sslopts() const { return m_sslopts; }
99
99
  const Options& options() const { return m_ctlopts; }
100
+ lcb_logprocs * logger() const { return m_logger; }
100
101
  unsigned loglevel() const { return m_loglevel; }
101
102
  bool logredact() const { return m_logredact; }
102
103
  const std::string& connstr() const { return m_connstr; }
@@ -126,6 +127,7 @@ private:
126
127
  std::set<int> m_transports;
127
128
  unsigned m_flags; /**< Internal flags */
128
129
  lcb_ipv6_t m_ipv6;
130
+ lcb_logprocs *m_logger;
129
131
  };
130
132
 
131
133
  #define LCB_SPECSCHEME_RAW "couchbase+explicit://"
@@ -17,6 +17,8 @@
17
17
 
18
18
  #include "internal.h"
19
19
 
20
+ #define LOGARGS(instance, lvl) instance->settings, "crypto", LCB_LOG_##lvl, __FILE__, __LINE__
21
+
20
22
  void lcbcrypto_ref(lcbcrypto_PROVIDER *provider)
21
23
  {
22
24
  provider->_refcnt++;
@@ -32,6 +34,10 @@ void lcbcrypto_unref(lcbcrypto_PROVIDER *provider)
32
34
 
33
35
  void lcbcrypto_register(lcb_t instance, const char *name, lcbcrypto_PROVIDER *provider)
34
36
  {
37
+ if (provider->version != 1) {
38
+ lcb_log(LOGARGS(instance, ERROR), "Unsupported version for \"%s\" crypto provider, ignoring", name);
39
+ return;
40
+ }
35
41
  std::map< std::string, lcbcrypto_PROVIDER * >::iterator old = instance->crypto->find(name);
36
42
  if (old != instance->crypto->end()) {
37
43
  lcbcrypto_unref(old->second);
@@ -54,38 +60,36 @@ static bool lcbcrypto_is_valid(lcbcrypto_PROVIDER *provider)
54
60
  if (!(provider && provider->_refcnt > 0)) {
55
61
  return false;
56
62
  }
57
- if (provider->version != 0) {
63
+ if (provider->version != 1) {
58
64
  return false;
59
65
  }
60
- if (provider->v.v0.sign && provider->v.v0.verify_signature == NULL) {
66
+ if (provider->v.v1.sign && provider->v.v1.verify_signature == NULL) {
61
67
  return false;
62
68
  }
63
- return provider->v.v0.load_key && provider->v.v0.encrypt && provider->v.v0.decrypt;
69
+ return provider->v.v1.encrypt && provider->v.v1.decrypt && provider->v.v1.get_key_id;
64
70
  }
65
71
 
66
- #define PROVIDER_LOAD_KEY(provider, type, keyid, key, nkey) \
67
- (provider)->v.v0.load_key((provider), (type), (keyid), (key), (nkey))
68
-
69
- #define PROVIDER_NEED_SIGN(provider) (provider)->v.v0.sign != NULL
72
+ #define PROVIDER_NEED_SIGN(provider) (provider)->v.v1.sign != NULL
70
73
  #define PROVIDER_SIGN(provider, parts, nparts, sig, nsig) \
71
- (provider)->v.v0.sign((provider), (parts), (nparts), (sig), (nsig));
74
+ (provider)->v.v1.sign((provider), (parts), (nparts), (sig), (nsig));
72
75
  #define PROVIDER_VERIFY_SIGNATURE(provider, parts, nparts, sig, nsig) \
73
- (provider)->v.v0.verify_signature((provider), (parts), (nparts), (sig), (nsig));
76
+ (provider)->v.v1.verify_signature((provider), (parts), (nparts), (sig), (nsig));
74
77
 
75
- #define PROVIDER_NEED_IV(provider) (provider)->v.v0.generate_iv != NULL
76
- #define PROVIDER_GENERATE_IV(provider, iv, niv) (provider)->v.v0.generate_iv((provider), (iv), (niv))
78
+ #define PROVIDER_NEED_IV(provider) (provider)->v.v1.generate_iv != NULL
79
+ #define PROVIDER_GENERATE_IV(provider, iv, niv) (provider)->v.v1.generate_iv((provider), (iv), (niv))
77
80
 
78
- #define PROVIDER_ENCRYPT(provider, ptext, nptext, key, nkey, iv, niv, ctext, nctext) \
79
- (provider)->v.v0.encrypt((provider), (ptext), (nptext), (key), (nkey), (iv), (niv), (ctext), (nctext));
80
- #define PROVIDER_DECRYPT(provider, ctext, nctext, key, nkey, iv, niv, ptext, nptext) \
81
- (provider)->v.v0.decrypt((provider), (ctext), (nctext), (key), (nkey), (iv), (niv), (ptext), (nptext));
81
+ #define PROVIDER_ENCRYPT(provider, ptext, nptext, iv, niv, ctext, nctext) \
82
+ (provider)->v.v1.encrypt((provider), (ptext), (nptext), (iv), (niv), (ctext), (nctext));
83
+ #define PROVIDER_DECRYPT(provider, ctext, nctext, iv, niv, ptext, nptext) \
84
+ (provider)->v.v1.decrypt((provider), (ctext), (nctext), (iv), (niv), (ptext), (nptext));
85
+
86
+ #define PROVIDER_GET_KEY_ID(provider) (provider)->v.v1.get_key_id((provider));
82
87
 
83
88
  #define PROVIDER_RELEASE_BYTES(provider, bytes) \
84
- if ((bytes) && (provider)->v.v0.release_bytes) { \
85
- (provider)->v.v0.release_bytes((provider), (bytes)); \
89
+ if ((bytes) && (provider)->v.v1.release_bytes) { \
90
+ (provider)->v.v1.release_bytes((provider), (bytes)); \
86
91
  }
87
92
 
88
-
89
93
  static lcbcrypto_PROVIDER *lcb_get_provider(const lcb_st *instance, const std::string &alg)
90
94
  {
91
95
  const lcb_st::lcb_ProviderMap::iterator provider_iterator = (*instance->crypto).find(alg);
@@ -102,26 +106,23 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
102
106
  return LCB_EINVAL;
103
107
  }
104
108
  bool changed = false;
105
- std::string prefix = (cmd->prefix == NULL) ? "__crypt_" : cmd->prefix;
109
+ std::string prefix = (cmd->prefix == NULL) ? LCBCRYPTO_DEFAULT_FIELD_PREFIX : cmd->prefix;
106
110
  for (size_t ii = 0; ii < cmd->nfields; ii++) {
107
111
  lcbcrypto_FIELDSPEC *field = cmd->fields + ii;
108
112
  lcb_error_t rc;
109
- uint8_t *key = NULL;
110
- size_t nkey = 0;
111
113
 
112
- lcbcrypto_PROVIDER *provider = lcb_get_provider(instance, field->alg);
113
- if (!lcbcrypto_is_valid(provider)) {
114
- continue;
114
+ if (field->name == NULL) {
115
+ lcb_log(LOGARGS(instance, WARN), "field name cannot be NULL");
116
+ return LCB_EINVAL;
115
117
  }
116
118
 
117
- rc = PROVIDER_LOAD_KEY(provider, LCBCRYPTO_KEY_ENCRYPT, field->kid, &key, &nkey);
118
- if (rc != LCB_SUCCESS) {
119
- PROVIDER_RELEASE_BYTES(provider, key);
120
- continue;
119
+ lcbcrypto_PROVIDER *provider = lcb_get_provider(instance, field->alg);
120
+ if (!lcbcrypto_is_valid(provider)) {
121
+ lcb_log(LOGARGS(instance, WARN), "Invalid crypto provider");
122
+ return LCB_EINVAL;
121
123
  }
122
124
 
123
125
  if (jdoc.isMember(field->name)) {
124
- std::string contents = Json::FastWriter().write(jdoc[field->name]);
125
126
  Json::Value encrypted;
126
127
  int ret;
127
128
 
@@ -131,26 +132,31 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
131
132
  lcb_SIZE nbiv = 0;
132
133
  if (PROVIDER_NEED_IV(provider)) {
133
134
  rc = PROVIDER_GENERATE_IV(provider, &iv, &niv);
134
- if (rc != 0) {
135
+ if (rc != LCB_SUCCESS) {
135
136
  PROVIDER_RELEASE_BYTES(provider, iv);
136
- continue;
137
+ lcb_log(LOGARGS(instance, WARN), "Unable to generate IV");
138
+ return rc;
137
139
  }
138
140
  ret = lcb_base64_encode2(reinterpret_cast< char * >(iv), niv, &biv, &nbiv);
139
141
  if (ret < 0) {
140
142
  free(biv);
141
143
  PROVIDER_RELEASE_BYTES(provider, iv);
142
- continue;
144
+ lcb_log(LOGARGS(instance, WARN), "Unable to encode IV as Base64 string");
145
+ return LCB_EINVAL;
143
146
  }
144
147
  encrypted["iv"] = biv;
145
148
  }
149
+
150
+ std::string contents = Json::FastWriter().write(jdoc[field->name]);
146
151
  const uint8_t *ptext = reinterpret_cast< const uint8_t * >(contents.c_str());
147
152
  uint8_t *ctext = NULL;
148
153
  size_t nptext = contents.size(), nctext = 0;
149
- rc = PROVIDER_ENCRYPT(provider, ptext, nptext, key, nkey, iv, niv, &ctext, &nctext);
154
+ rc = PROVIDER_ENCRYPT(provider, ptext, nptext, iv, niv, &ctext, &nctext);
150
155
  PROVIDER_RELEASE_BYTES(provider, iv);
151
156
  if (rc != LCB_SUCCESS) {
152
157
  PROVIDER_RELEASE_BYTES(provider, ctext);
153
- continue;
158
+ lcb_log(LOGARGS(instance, WARN), "Unable to encrypt field");
159
+ return rc;
154
160
  }
155
161
  char *btext = NULL;
156
162
  lcb_SIZE nbtext = 0;
@@ -158,9 +164,12 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
158
164
  PROVIDER_RELEASE_BYTES(provider, ctext);
159
165
  if (ret < 0) {
160
166
  free(btext);
161
- continue;
167
+ lcb_log(LOGARGS(instance, WARN), "Unable to encode encrypted field as Base64 string");
168
+ return LCB_EINVAL;
162
169
  }
163
170
  encrypted["ciphertext"] = btext;
171
+ std::string kid = PROVIDER_GET_KEY_ID(provider);
172
+ encrypted["kid"] = kid;
164
173
 
165
174
  if (PROVIDER_NEED_SIGN(provider)) {
166
175
  lcbcrypto_SIGV parts[4] = {};
@@ -168,8 +177,8 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
168
177
  uint8_t *sig = NULL;
169
178
  size_t nsig = 0;
170
179
 
171
- parts[nparts].data = reinterpret_cast< const uint8_t * >(field->kid);
172
- parts[nparts].len = strlen(field->kid);
180
+ parts[nparts].data = reinterpret_cast< const uint8_t * >(kid.c_str());
181
+ parts[nparts].len = kid.size();
173
182
  nparts++;
174
183
  parts[nparts].data = reinterpret_cast< const uint8_t * >(field->alg);
175
184
  parts[nparts].len = strlen(field->alg);
@@ -186,7 +195,8 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
186
195
  rc = PROVIDER_SIGN(provider, parts, nparts, &sig, &nsig);
187
196
  if (rc != LCB_SUCCESS) {
188
197
  PROVIDER_RELEASE_BYTES(provider, sig);
189
- continue;
198
+ lcb_log(LOGARGS(instance, WARN), "Unable to sign encrypted field");
199
+ return rc;
190
200
  }
191
201
  char *bsig = NULL;
192
202
  lcb_SIZE nbsig = 0;
@@ -194,14 +204,14 @@ lcb_error_t lcbcrypto_encrypt_fields(lcb_t instance, lcbcrypto_CMDENCRYPT *cmd)
194
204
  PROVIDER_RELEASE_BYTES(provider, sig);
195
205
  if (ret < 0) {
196
206
  free(bsig);
197
- continue;
207
+ lcb_log(LOGARGS(instance, WARN), "Unable to encode signature as Base64 string");
208
+ return LCB_EINVAL;
198
209
  }
199
210
  encrypted["sig"] = bsig;
200
211
  free(bsig);
201
212
  }
202
213
  free(biv);
203
214
  free(btext);
204
- encrypted["kid"] = field->kid;
205
215
  encrypted["alg"] = field->alg;
206
216
  jdoc[prefix + field->name] = encrypted;
207
217
  jdoc.removeMember(field->name);
@@ -231,34 +241,45 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
231
241
  }
232
242
 
233
243
  bool changed = false;
234
- std::string prefix = (cmd->prefix == NULL) ? "__crypt_" : cmd->prefix;
244
+ std::string prefix = (cmd->prefix == NULL) ? LCBCRYPTO_DEFAULT_FIELD_PREFIX : cmd->prefix;
235
245
 
236
- const Json::Value::Members names = jdoc.getMemberNames();
237
- for (Json::Value::Members::const_iterator ii = names.begin(); ii != names.end(); ii++) {
238
- const std::string &name = *ii;
239
- if (name.size() <= prefix.size()) {
240
- continue;
246
+ for (size_t ii = 0; ii < cmd->nfields; ii++) {
247
+ lcbcrypto_FIELDSPEC *field = cmd->fields + ii;
248
+
249
+ if (field->name == NULL) {
250
+ lcb_log(LOGARGS(instance, WARN), "field name cannot be NULL");
251
+ return LCB_EINVAL;
252
+ }
253
+ lcbcrypto_PROVIDER *provider = lcb_get_provider(instance, field->alg);
254
+ if (!lcbcrypto_is_valid(provider)) {
255
+ lcb_log(LOGARGS(instance, WARN), "Invalid crypto provider");
256
+ return LCB_EINVAL;
241
257
  }
242
- if (prefix.compare(0, prefix.size(), name, 0, prefix.size()) != 0) {
258
+
259
+ std::string name = prefix + field->name;
260
+ if (!jdoc.isMember(name)) {
243
261
  continue;
244
262
  }
245
263
  Json::Value &encrypted = jdoc[name];
246
264
  if (!encrypted.isObject()) {
247
- continue;
248
- }
249
-
250
- Json::Value &jalg = encrypted["alg"];
251
- if (!jalg.isString()) {
252
- continue;
265
+ lcb_log(LOGARGS(instance, WARN), "Expected encrypted field to be an JSON object");
266
+ return LCB_EINVAL;
253
267
  }
254
- const std::string &alg = jalg.asString();
255
268
 
256
269
  Json::Value &jkid = encrypted["kid"];
257
270
  if (!jkid.isString()) {
258
- continue;
271
+ lcb_log(LOGARGS(instance, WARN), "Expected \"kid\" to be a JSON string");
272
+ return LCB_EINVAL;
259
273
  }
260
274
  const std::string &kid = jkid.asString();
261
275
 
276
+ Json::Value &jalg = encrypted["alg"];
277
+ if (!jalg.isString()) {
278
+ lcb_log(LOGARGS(instance, WARN), "Expected provider alias \"alg\" to be a JSON string");
279
+ return LCB_EINVAL;
280
+ }
281
+ const std::string &alg = jalg.asString();
282
+
262
283
  Json::Value &jiv = encrypted["iv"];
263
284
  const char *biv = NULL;
264
285
  size_t nbiv = 0;
@@ -270,21 +291,18 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
270
291
  int ret;
271
292
  lcb_error_t rc;
272
293
 
273
- lcbcrypto_PROVIDER *provider = lcb_get_provider(instance, alg);
274
- if (!lcbcrypto_is_valid(provider)) {
275
- continue;
276
- }
277
294
  Json::Value &jctext = encrypted["ciphertext"];
278
295
  if (!jctext.isString()) {
279
- continue;
296
+ lcb_log(LOGARGS(instance, WARN), "Expected encrypted field \"ciphertext\" to be a JSON string");
297
+ return LCB_EINVAL;
280
298
  }
281
299
  const std::string &btext = jctext.asString();
282
300
 
283
301
  if (PROVIDER_NEED_SIGN(provider)) {
284
302
  Json::Value &jsig = encrypted["sig"];
285
303
  if (!jsig.isString()) {
286
- /* TODO: warn about missing signature? */
287
- continue;
304
+ lcb_log(LOGARGS(instance, WARN), "Expected signature field \"sig\" to be a JSON string");
305
+ return LCB_EINVAL;
288
306
  }
289
307
  uint8_t *sig = NULL;
290
308
  lcb_SIZE nsig = 0;
@@ -292,7 +310,8 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
292
310
  ret = lcb_base64_decode2(bsig.c_str(), bsig.size(), reinterpret_cast< char ** >(&sig), &nsig);
293
311
  if (ret < 0) {
294
312
  PROVIDER_RELEASE_BYTES(provider, sig);
295
- continue;
313
+ lcb_log(LOGARGS(instance, WARN), "Unable to decode signature as Base64 string");
314
+ return LCB_EINVAL;
296
315
  }
297
316
 
298
317
  lcbcrypto_SIGV parts[4] = {};
@@ -316,7 +335,8 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
316
335
  rc = PROVIDER_VERIFY_SIGNATURE(provider, parts, nparts, sig, nsig);
317
336
  free(sig);
318
337
  if (rc != LCB_SUCCESS) {
319
- continue;
338
+ lcb_log(LOGARGS(instance, WARN), "Signature verification for encrypted field \"ciphertext\" failed");
339
+ return rc;
320
340
  }
321
341
  }
322
342
 
@@ -324,16 +344,8 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
324
344
  lcb_SIZE nctext = 0;
325
345
  ret = lcb_base64_decode2(btext.c_str(), btext.size(), reinterpret_cast< char ** >(&ctext), &nctext);
326
346
  if (ret < 0) {
327
- continue;
328
- }
329
-
330
- uint8_t *key = NULL;
331
- size_t nkey = 0;
332
- rc = PROVIDER_LOAD_KEY(provider, LCBCRYPTO_KEY_DECRYPT, kid.c_str(), &key, &nkey);
333
- if (rc != LCB_SUCCESS) {
334
- free(ctext);
335
- PROVIDER_RELEASE_BYTES(provider, key);
336
- continue;
347
+ lcb_log(LOGARGS(instance, WARN), "Unable to decode encrypted field \"ciphertext\" as Base64 string");
348
+ return LCB_EINVAL;
337
349
  }
338
350
 
339
351
  uint8_t *iv = NULL;
@@ -342,26 +354,27 @@ lcb_error_t lcbcrypto_decrypt_fields(lcb_t instance, lcbcrypto_CMDDECRYPT *cmd)
342
354
  ret = lcb_base64_decode2(biv, nbiv, reinterpret_cast< char ** >(&iv), &niv);
343
355
  if (ret < 0) {
344
356
  free(ctext);
345
- PROVIDER_RELEASE_BYTES(provider, key);
346
- continue;
357
+ lcb_log(LOGARGS(instance, WARN), "Unable to decode IV field \"iv\" as Base64 string");
358
+ return LCB_EINVAL;
347
359
  }
348
360
  }
349
361
 
350
362
  uint8_t *ptext = NULL;
351
363
  size_t nptext = 0;
352
- rc = PROVIDER_DECRYPT(provider, ctext, nctext, key, nkey, iv, niv, &ptext, &nptext);
353
- PROVIDER_RELEASE_BYTES(provider, key);
364
+ rc = PROVIDER_DECRYPT(provider, ctext, nctext, iv, niv, &ptext, &nptext);
354
365
  free(ctext);
355
366
  if (rc != LCB_SUCCESS) {
356
367
  PROVIDER_RELEASE_BYTES(provider, ptext);
357
- continue;
368
+ lcb_log(LOGARGS(instance, WARN), "Unable to decrypt encrypted field");
369
+ return rc;
358
370
  }
359
371
  Json::Value frag;
360
372
  char *json = reinterpret_cast< char * >(ptext);
361
373
  bool valid_json = Json::Reader().parse(json, json + nptext, frag);
362
374
  PROVIDER_RELEASE_BYTES(provider, ptext);
363
375
  if (!valid_json) {
364
- continue;
376
+ lcb_log(LOGARGS(instance, WARN), "Result of decryption is not valid JSON");
377
+ return LCB_EINVAL;
365
378
  }
366
379
  jdoc[name.substr(prefix.size())] = frag;
367
380
  jdoc.removeMember(name);