libcouchbase 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
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);