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
@@ -88,7 +88,7 @@ lcb::dnssrv_query(const char* name, lcb::Hostlist& hostlist)
88
88
  }
89
89
  #endif /* HAVE_RES_SEARCH */
90
90
 
91
- #else
91
+ #elif defined(_MSC_VER)
92
92
  #include <windns.h>
93
93
  #define CAN_SRV_LOOKUP
94
94
  /* Implement via DnsQuery() */
@@ -679,7 +679,6 @@ H_observe(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response
679
679
  rd->procs->handler(pipeline, request, resp.rc, &resp);
680
680
  }
681
681
  }
682
- TRACE_OBSERVE_END(root, request, response);
683
682
  }
684
683
 
685
684
  static void
@@ -79,6 +79,7 @@ struct Request {
79
79
  return reqtype == LCB_HTTP_TYPE_N1QL ||
80
80
  reqtype == LCB_HTTP_TYPE_VIEW ||
81
81
  reqtype == LCB_HTTP_TYPE_FTS ||
82
+ reqtype == LCB_HTTP_TYPE_PING ||
82
83
  reqtype == LCB_HTTP_TYPE_CBAS;
83
84
  }
84
85
 
@@ -412,8 +412,7 @@ Request::get_api_node(lcb_error_t &rc)
412
412
  }
413
413
 
414
414
  const lcbvb_SVCTYPE svc = httype2svctype(reqtype);
415
- const lcbvb_SVCMODE mode = LCBT_SETTING(instance, sslopts) ?
416
- LCBVB_SVCMODE_SSL : LCBVB_SVCMODE_PLAIN;
415
+ const lcbvb_SVCMODE mode = LCBT_SETTING_SVCMODE(instance);
417
416
 
418
417
  lcbvb_CONFIG *vbc = LCBT_VBCONFIG(instance);
419
418
 
@@ -451,7 +451,10 @@ lcb_error_t lcb_create(lcb_t *instance,
451
451
  goto GT_DONE;
452
452
  }
453
453
 
454
- settings->logger = lcb_init_console_logger();
454
+ settings->logger = spec.logger();
455
+ if (settings->logger == NULL) {
456
+ settings->logger = lcb_init_console_logger();
457
+ }
455
458
  settings->iid = lcb_next_rand32();
456
459
  if (spec.loglevel()) {
457
460
  lcb_U32 val = spec.loglevel();
@@ -615,9 +618,25 @@ void lcb_destroy(lcb_t instance)
615
618
  DESTROY(lcb_vbguess_destroy, vbguess);
616
619
  DESTROY(lcb_n1qlcache_destroy, n1ql_cache);
617
620
 
621
+ if (instance->cmdq.pipelines) {
622
+ unsigned ii;
623
+ for (ii = 0; ii < instance->cmdq.npipelines; ii++) {
624
+ lcb::Server *server = static_cast<lcb::Server*>(instance->cmdq.pipelines[ii]);
625
+ if (server) {
626
+ server->instance = NULL;
627
+ }
628
+ }
629
+ }
618
630
  mcreq_queue_cleanup(&instance->cmdq);
619
631
  lcb_aspend_cleanup(po);
620
632
 
633
+ #ifdef LCB_TRACING
634
+ if (instance->settings && instance->settings->tracer) {
635
+ lcbtrace_destroy(instance->settings->tracer);
636
+ instance->settings->tracer = NULL;
637
+ }
638
+ #endif
639
+
621
640
  if (instance->iotable && instance->iotable->refcount > 1 &&
622
641
  instance->settings && instance->settings->syncdtor) {
623
642
  /* create an async object */
@@ -676,7 +695,7 @@ lcb_st::find_server(const lcb_host_t& host) const
676
695
  unsigned ii;
677
696
  for (ii = 0; ii < cmdq.npipelines; ii++) {
678
697
  lcb::Server *server = static_cast<lcb::Server*>(cmdq.pipelines[ii]);
679
- if (lcb_host_equals(&server->get_host(), &host)) {
698
+ if (server && lcb_host_equals(&server->get_host(), &host)) {
680
699
  return server;
681
700
  }
682
701
  }
@@ -196,6 +196,7 @@ struct lcb_st {
196
196
  #define LCBT_NREPLICAS(instance) LCBVB_NREPLICAS(LCBT_VBCONFIG(instance))
197
197
  #define LCBT_GET_SERVER(instance, ix) (instance)->cmdq.pipelines[ix]
198
198
  #define LCBT_SETTING(instance, name) (instance)->settings->name
199
+ #define LCBT_SETTING_SVCMODE(instance) (((instance)->settings->sslopts & LCB_SSL_ENABLED) ? LCBVB_SVCMODE_SSL : LCBVB_SVCMODE_PLAIN)
199
200
 
200
201
  void lcb_initialize_packet_handlers(lcb_t instance);
201
202
 
@@ -31,11 +31,11 @@
31
31
  } \
32
32
  } while (0)
33
33
 
34
- #include "rw-inl.h"
35
- #include "ctx-log-inl.h"
36
34
 
37
35
  #define LOGARGS(c, lvl) (c)->sock->settings, "ioctx", LCB_LOG_##lvl, __FILE__, __LINE__
38
36
 
37
+ #include "rw-inl.h"
38
+
39
39
  typedef enum {
40
40
  ES_ACTIVE = 0,
41
41
  ES_DETACHED
@@ -385,6 +385,18 @@ Cr_handler(lcb_sockdata_t *sd, lcb_ssize_t nr, void *arg)
385
385
  rdb_rdend(&ctx->ior, nr);
386
386
  total = rdb_get_nused(&ctx->ior);
387
387
  if (total >= ctx->rdwant) {
388
+ #ifdef LCB_DUMP_PACKETS
389
+ {
390
+ char *b64 = NULL;
391
+ lcb_SIZE nb64 = 0;
392
+ char *buf = calloc(total, sizeof(char));
393
+ rdb_copyread(&ctx->ior, buf, total);
394
+ lcb_base64_encode2(buf, total, &b64, &nb64);
395
+ lcb_log(LOGARGS(ctx, TRACE), CTX_LOGFMT "pkt,rcv: size=%d, %.*s", CTX_LOGID(ctx), (int)nb64, (int)nb64, b64);
396
+ free(b64);
397
+ free(buf);
398
+ }
399
+ #endif
388
400
  invoke_read_cb(ctx, total);
389
401
  }
390
402
  CTX_INCR_METRIC(ctx, bytes_received, total);
@@ -421,7 +433,7 @@ C_schedule(lcbio_CTX *ctx)
421
433
 
422
434
  if (ctx->output && ctx->output->rb.nbytes) {
423
435
  /** Schedule a write */
424
- lcb_IOV iov[2];
436
+ lcb_IOV iov[2] = {0};
425
437
  unsigned niov;
426
438
 
427
439
  ringbuffer_get_iov(&ctx->output->rb, RINGBUFFER_READ, iov);
@@ -433,6 +445,15 @@ C_schedule(lcbio_CTX *ctx)
433
445
  } else {
434
446
  ctx->output = NULL;
435
447
  ctx->npending++;
448
+ #ifdef LCB_DUMP_PACKETS
449
+ {
450
+ char *b64 = NULL;
451
+ int nb64 = 0;
452
+ lcb_base64_encode_iov((lcb_IOV *)iov, niov, iov[0].iov_len + iov[1].iov_len, &b64, &nb64);
453
+ lcb_log(LOGARGS(ctx, TRACE), CTX_LOGFMT "pkt,snd: size=%d, %.*s", CTX_LOGID(ctx), nb64, nb64, b64);
454
+ free(b64);
455
+ }
456
+ #endif
436
457
  }
437
458
  }
438
459
 
@@ -109,7 +109,7 @@ lcb_error_t
109
109
  lcbio_mklcberr(lcbio_OSERR in, const lcb_settings *settings)
110
110
  {
111
111
  if (settings->detailed_neterr == 0) {
112
- lcb_log(settings, "lcbio", LCB_LOG_INFO, __FILE__, __LINE__, "Translating errno=%d, lcb=0x%x to NETWORK_ERROR",
112
+ lcb_log(settings, "lcbio", LCB_LOG_WARN, __FILE__, __LINE__, "Translating errno=%d, lcb=0x%x to NETWORK_ERROR",
113
113
  in, ioerr2lcberr(in, settings));
114
114
  return LCB_NETWORK_ERROR;
115
115
  }
@@ -20,6 +20,9 @@
20
20
  */
21
21
  #include <errno.h>
22
22
  #include <limits.h> /* For IOV_MAX */
23
+ #include "ctx-log-inl.h"
24
+ #include "strcodecs/strcodecs.h"
25
+
23
26
  #ifndef INLINE
24
27
  #ifdef _MSC_VER
25
28
  #define INLINE __inline
@@ -57,6 +60,15 @@ lcbio_E_rdb_slurp(lcbio_CTX *ctx, rdb_IOROPE *ior)
57
60
  GT_READ:
58
61
  rv = IOT_V0IO(iot).recvv(IOT_ARG(iot), CTX_FD(ctx), iov, niov);
59
62
  if (rv > 0) {
63
+ #ifdef LCB_DUMP_PACKETS
64
+ {
65
+ char *b64 = NULL;
66
+ int nb64 = 0;
67
+ lcb_base64_encode_iov((lcb_IOV *)iov, niov, rv, &b64, &nb64);
68
+ lcb_log(LOGARGS(ctx, TRACE), CTX_LOGFMT "pkt,rcv: size=%d, %.*s", CTX_LOGID(ctx), nb64, nb64, b64);
69
+ free(b64);
70
+ }
71
+ #endif
60
72
  rdb_rdend(ior, rv);
61
73
  if (rdsize && (total_nr += rv) >= rdsize) {
62
74
  return LCBIO_PENDING;
@@ -83,7 +95,7 @@ lcbio_E_rdb_slurp(lcbio_CTX *ctx, rdb_IOROPE *ior)
83
95
  static INLINE lcbio_IOSTATUS
84
96
  lcbio_E_rb_write(lcbio_CTX *ctx, ringbuffer_t *buf)
85
97
  {
86
- lcb_IOV iov[2];
98
+ lcb_IOV iov[2] = {0};
87
99
  lcb_ssize_t nw;
88
100
  lcbio_TABLE *iot = ctx->io;
89
101
  while (buf->nbytes) {
@@ -108,6 +120,15 @@ lcbio_E_rb_write(lcbio_CTX *ctx, ringbuffer_t *buf)
108
120
  }
109
121
  }
110
122
  if (nw) {
123
+ #ifdef LCB_DUMP_PACKETS
124
+ {
125
+ char *b64 = NULL;
126
+ int nb64 = 0;
127
+ lcb_base64_encode_iov((lcb_IOV *)iov, niov, nw, &b64, &nb64);
128
+ lcb_log(LOGARGS(ctx, TRACE), CTX_LOGFMT "pkt,snd: size=%d, %.*s", CTX_LOGID(ctx), nb64, nb64, b64);
129
+ free(b64);
130
+ }
131
+ #endif
111
132
  ringbuffer_consumed(buf, nw);
112
133
  CTX_INCR_METRIC(ctx, bytes_sent, nw);
113
134
  }
@@ -66,7 +66,9 @@ lcbio_pSSLCTX lcbio_ssl_new__fallback(const char *, const char *, const char *,
66
66
  #ifndef LCB_NO_SSL
67
67
  /**
68
68
  * Create a new SSL context to be used to establish SSL policy.
69
+ * @param tsfile Path to trusted store file
69
70
  * @param cafile Optional path to CA file
71
+ * @param keyfile Path to private key file
70
72
  * @param noverify To not attempt to verify server's certificate
71
73
  * @param errp a pointer to contain the error code if initialization failed
72
74
  * @param settings settings structure, used for logging.
@@ -54,18 +54,25 @@ class FragBufSource : public snappy::Source
54
54
 
55
55
  virtual void Skip(size_t n)
56
56
  {
57
- lcb_IOV &v = buf->iov[idx];
58
- if (ptr == static_cast< const char * >(v.iov_base) && n == v.iov_len) {
59
- ptr = static_cast< const char * >(buf->iov[++idx].iov_base);
60
- } else {
61
- ptr += n;
62
- if (static_cast< size_t >(ptr - static_cast< const char * >(v.iov_base)) == v.iov_len) {
63
- ptr = static_cast< const char * >(buf->iov[++idx].iov_base);
57
+ do {
58
+ size_t spanleft = buf->iov[idx].iov_len - (ptr - static_cast< const char * >(buf->iov[idx].iov_base));
59
+ if (n < spanleft) {
60
+ ptr += n;
61
+ left -= n;
62
+ break;
64
63
  }
65
- }
66
- left -= n;
67
- if (left == 0) {
64
+ if (idx + 1 >= buf->niov) {
65
+ left = 0;
66
+ ptr = NULL;
67
+ break;
68
+ }
69
+ left -= spanleft;
70
+ n -= spanleft;
71
+ ptr = static_cast< const char * >(buf->iov[++idx].iov_base);
72
+ } while (n > 0);
73
+ if (left == 0 || idx >= buf->niov) {
68
74
  ptr = NULL;
75
+ left = 0;
69
76
  }
70
77
  }
71
78
 
@@ -125,7 +132,7 @@ int mcreq_compress_value(mc_PIPELINE *pl, mc_PACKET *pkt, const lcb_VALBUF *vbuf
125
132
  compsize = sink.CurrentDestination() - SPAN_BUFFER(outspan);
126
133
  delete source;
127
134
 
128
- if (compsize == 0 || compsize / origsize > settings->compress_min_ratio) {
135
+ if (compsize == 0 || (((float)compsize / origsize) > settings->compress_min_ratio)) {
129
136
  netbuf_mblock_release(&pl->nbmgr, outspan);
130
137
  *should_compress = 0;
131
138
  mcreq_reserve_value(pl, pkt, vbuf);
@@ -640,6 +640,8 @@ mcreq_queue_cleanup(mc_CMDQUEUE *queue)
640
640
  }
641
641
  free(queue->scheds);
642
642
  free(queue->pipelines);
643
+ queue->pipelines = NULL;
644
+ queue->npipelines = 0;
643
645
  queue->scheds = NULL;
644
646
  }
645
647
 
@@ -699,7 +699,7 @@ mcreq_get_bodysize(const mc_PACKET *packet);
699
699
 
700
700
  /**
701
701
  * @brief get the total packet size (header+body)
702
- * @param pkt the packet
702
+ * @param packet the packet
703
703
  * @return the total size
704
704
  */
705
705
  uint32_t
@@ -46,7 +46,7 @@ static void
46
46
  on_flush_ready(lcbio_CTX *ctx)
47
47
  {
48
48
  Server *server = Server::get(ctx);
49
- nb_IOV iov[MCREQ_MAXIOV];
49
+ nb_IOV iov[MCREQ_MAXIOV] = {};
50
50
  int ready;
51
51
 
52
52
  do {
@@ -56,6 +56,15 @@ on_flush_ready(lcbio_CTX *ctx)
56
56
  if (!nb) {
57
57
  return;
58
58
  }
59
+ #ifdef LCB_DUMP_PACKETS
60
+ {
61
+ char *b64 = NULL;
62
+ int nb64 = 0;
63
+ lcb_base64_encode_iov((lcb_IOV *)iov, niov, nb, &b64, &nb64);
64
+ lcb_log(LOGARGS(server, TRACE), LOGFMT "pkt,snd,fill: size=%d, %.*s", LOGID(server), nb64, nb64, b64);
65
+ free(b64);
66
+ }
67
+ #endif
59
68
  ready = lcbio_ctx_put_ex(ctx, (lcb_IOV *)iov, niov, nb);
60
69
  } while (ready);
61
70
  lcbio_ctx_wwant(ctx);
@@ -70,6 +79,9 @@ on_flush_done(lcbio_CTX *ctx, unsigned expected, unsigned actual)
70
79
  now = gethrtime();
71
80
  }
72
81
 
82
+ #ifdef LCB_DUMP_PACKETS
83
+ lcb_log(LOGARGS(server, TRACE), LOGFMT "pkt,snd,flush: expected=%u, actual=%u", LOGID(server), expected, actual);
84
+ #endif
73
85
  mcreq_flush_done_ex(server, actual, expected, now);
74
86
  server->check_closed();
75
87
  }
@@ -197,6 +209,14 @@ static bool is_fastpath_error(uint16_t rc) {
197
209
  case PROTOCOL_BINARY_RESPONSE_SUBDOC_DELTA_ERANGE:
198
210
  case PROTOCOL_BINARY_RESPONSE_SUBDOC_INVALID_COMBO:
199
211
  case PROTOCOL_BINARY_RESPONSE_SUBDOC_MULTI_PATH_FAILURE:
212
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_SUCCESS_DELETED:
213
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_INVALID_FLAG_COMBO:
214
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_INVALID_KEY_COMBO:
215
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_UNKNOWN_MACRO:
216
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_UNKNOWN_VATTR:
217
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_CANT_MODIFY_VATTR:
218
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_MULTI_PATH_FAILURE_DELETED:
219
+ case PROTOCOL_BINARY_RESPONSE_SUBDOC_INVALID_XATTR_ORDER:
200
220
  case PROTOCOL_BINARY_RESPONSE_EACCESS:
201
221
  return true;
202
222
  default:
@@ -357,7 +377,7 @@ Server::try_read(lcbio_CTX *ctx, rdb_IOROPE *ior)
357
377
 
358
378
  if (!request) {
359
379
  MC_INCR_METRIC(this, packets_ownerless, 1);
360
- lcb_log(LOGARGS_T(WARN), LOGFMT "Server sent us reply for a timed-out command. (OP=0x%x, RC=0x%x, SEQ=%u)", LOGID_T(), mcresp.opcode(), mcresp.status(), mcresp.opaque());
380
+ lcb_log(LOGARGS_T(DEBUG), LOGFMT "Server sent us reply for a timed-out command. (OP=0x%x, RC=0x%x, SEQ=%u)", LOGID_T(), mcresp.opcode(), mcresp.status(), mcresp.opaque());
361
381
  rdb_consumed(ior, pktsize);
362
382
  return PKT_READ_COMPLETE;
363
383
  }
@@ -475,6 +495,100 @@ fail_callback(mc_PIPELINE *pipeline, mc_PACKET *pkt, lcb_error_t err, void *) {
475
495
  static_cast<Server*>(pipeline)->purge_single(pkt, err);
476
496
  }
477
497
 
498
+ static const char *opcode_name(uint8_t code)
499
+ {
500
+ switch (code) {
501
+ case PROTOCOL_BINARY_CMD_GET:
502
+ return "get";
503
+ case PROTOCOL_BINARY_CMD_SET:
504
+ return "set";
505
+ case PROTOCOL_BINARY_CMD_ADD:
506
+ return "add";
507
+ case PROTOCOL_BINARY_CMD_REPLACE:
508
+ return "replace";
509
+ case PROTOCOL_BINARY_CMD_DELETE:
510
+ return "delete";
511
+ case PROTOCOL_BINARY_CMD_INCREMENT:
512
+ return "incr";
513
+ case PROTOCOL_BINARY_CMD_DECREMENT:
514
+ return "decr";
515
+ case PROTOCOL_BINARY_CMD_FLUSH:
516
+ return "flush";
517
+ case PROTOCOL_BINARY_CMD_GETQ:
518
+ return "getq";
519
+ case PROTOCOL_BINARY_CMD_NOOP:
520
+ return "noop";
521
+ case PROTOCOL_BINARY_CMD_VERSION:
522
+ return "version";
523
+ case PROTOCOL_BINARY_CMD_APPEND:
524
+ return "append";
525
+ case PROTOCOL_BINARY_CMD_PREPEND:
526
+ return "prepend";
527
+ case PROTOCOL_BINARY_CMD_STAT:
528
+ return "stat";
529
+ case PROTOCOL_BINARY_CMD_VERBOSITY:
530
+ return "verbosity";
531
+ case PROTOCOL_BINARY_CMD_TOUCH:
532
+ return "touch";
533
+ case PROTOCOL_BINARY_CMD_GAT:
534
+ return "gat";
535
+ case PROTOCOL_BINARY_CMD_HELLO:
536
+ return "hello";
537
+ case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
538
+ return "sasl_list_mechs";
539
+ case PROTOCOL_BINARY_CMD_SASL_AUTH:
540
+ return "sasl_auth";
541
+ case PROTOCOL_BINARY_CMD_SASL_STEP:
542
+ return "sasl_step";
543
+ case PROTOCOL_BINARY_CMD_GET_REPLICA:
544
+ return "get_replica";
545
+ case PROTOCOL_BINARY_CMD_SELECT_BUCKET:
546
+ return "select_bucket";
547
+ case PROTOCOL_BINARY_CMD_OBSERVE_SEQNO:
548
+ return "observe_seqno";
549
+ case PROTOCOL_BINARY_CMD_OBSERVE:
550
+ return "observe";
551
+ case PROTOCOL_BINARY_CMD_GET_LOCKED:
552
+ return "get_locked";
553
+ case PROTOCOL_BINARY_CMD_UNLOCK_KEY:
554
+ return "unlock_key";
555
+ case PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG:
556
+ return "get_cluster_config";
557
+ case PROTOCOL_BINARY_CMD_SUBDOC_GET:
558
+ return "subdoc_get";
559
+ case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS:
560
+ return "subdoc_exists";
561
+ case PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD:
562
+ return "subdoc_dict_add";
563
+ case PROTOCOL_BINARY_CMD_SUBDOC_DICT_UPSERT:
564
+ return "subdoc_dict_upsert";
565
+ case PROTOCOL_BINARY_CMD_SUBDOC_DELETE:
566
+ return "subdoc_delete";
567
+ case PROTOCOL_BINARY_CMD_SUBDOC_REPLACE:
568
+ return "subdoc_replace";
569
+ case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_LAST:
570
+ return "subdoc_array_push_last";
571
+ case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_FIRST:
572
+ return "subdoc_array_push_first";
573
+ case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_INSERT:
574
+ return "subdoc_array_insert";
575
+ case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_ADD_UNIQUE:
576
+ return "subdoc_array_add_unique";
577
+ case PROTOCOL_BINARY_CMD_SUBDOC_COUNTER:
578
+ return "subdoc_counter";
579
+ case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP:
580
+ return "subdoc_multi_lookup";
581
+ case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION:
582
+ return "subdoc_multi_mutation";
583
+ case PROTOCOL_BINARY_CMD_SUBDOC_GET_COUNT:
584
+ return "subdoc_get_count";
585
+ case PROTOCOL_BINARY_CMD_GET_ERROR_MAP:
586
+ return "get_error_map";
587
+ default:
588
+ return "unknown";
589
+ }
590
+ }
591
+
478
592
  void Server::purge_single(mc_PACKET *pkt, lcb_error_t err) {
479
593
  if (maybe_retry_packet(pkt, err)) {
480
594
  return;
@@ -502,7 +616,39 @@ void Server::purge_single(mc_PACKET *pkt, lcb_error_t err) {
502
616
  #ifdef LCB_TRACING
503
617
  lcbtrace_span_set_orphaned(MCREQ_PKT_RDATA(pkt)->span, true);
504
618
  #endif
505
- lcb_log(LOGARGS_T(WARN), LOGFMT "Failing command (pkt=%p, opaque=%lu, opcode=0x%x) with error %s", LOGID_T(), (void*)pkt, (unsigned long)pkt->opaque, hdr.request.opcode, lcb_strerror_short(err));
619
+ if (err == LCB_ETIMEDOUT && settings->use_tracing) {
620
+ Json::Value info;
621
+
622
+ char opid[30] = {};
623
+ snprintf(opid, sizeof(opid), "kv:%s", opcode_name(hdr.request.opcode));
624
+ info["s"] = opid;
625
+ info["b"] = settings->bucket;
626
+ info["t"] = settings->operation_timeout;
627
+
628
+ const lcb_host_t &remote = get_host();
629
+ std::string rhost;
630
+ if (remote.ipv6) {
631
+ rhost.append("[").append(remote.host).append("]:").append(remote.port);
632
+ } else {
633
+ rhost.append(remote.host).append(":").append(remote.port);
634
+ }
635
+ info["r"] = rhost.c_str();
636
+
637
+ if (connctx) {
638
+ char local_id[54] = {};
639
+ snprintf(local_id, sizeof(local_id), "%016" PRIx64 "/%016" PRIx64 "/%x",
640
+ (lcb_U64)settings->iid, connctx->sock->id, (int)pkt->opaque);
641
+ info["i"] = local_id;
642
+ info["l"] = lcbio__inet_ntop(&connctx->sock->info->sa_local).c_str();
643
+ }
644
+ std::string msg(Json::FastWriter().write(info));
645
+ if (msg.size() > 1) {
646
+ lcb_log(LOGARGS(instance, WARN), "Failing command with error %s: %.*s",
647
+ lcb_strerror_short(err), (int)(msg.size() - 1), msg.c_str());
648
+ }
649
+ } else {
650
+ lcb_log(LOGARGS_T(WARN), LOGFMT "Failing command (pkt=%p, opaque=%lu, opcode=0x%x) with error %s", LOGID_T(), (void*)pkt, (unsigned long)pkt->opaque, hdr.request.opcode, lcb_strerror_short(err));
651
+ }
506
652
  int rv = mcreq_dispatch_response(this, pkt, &resp, err);
507
653
  lcb_assert(rv == 0);
508
654
  }
@@ -579,7 +725,7 @@ void Server::io_timeout()
579
725
  Server::REFRESH_ONFAILED);
580
726
  if (npurged) {
581
727
  MC_INCR_METRIC(this, packets_timeout, npurged);
582
- lcb_log(LOGARGS_T(ERR), LOGFMT "Server timed out. Some commands have failed", LOGID_T());
728
+ lcb_log(LOGARGS_T(DEBUG), LOGFMT "Server timed out. Some commands have failed", LOGID_T());
583
729
  }
584
730
 
585
731
  uint32_t next_us = next_timeout();
@@ -706,8 +852,7 @@ Server::Server(lcb_t instance_, int ix)
706
852
 
707
853
  const char *datahost = lcbvb_get_hostport(
708
854
  LCBT_VBCONFIG(instance), ix,
709
- LCBVB_SVCTYPE_DATA, settings->sslopts & LCB_SSL_ENABLED ?
710
- LCBVB_SVCMODE_SSL : LCBVB_SVCMODE_PLAIN);
855
+ LCBVB_SVCTYPE_DATA, LCBT_SETTING_SVCMODE(instance));
711
856
  if (datahost) {
712
857
  lcb_host_parsez(curhost, datahost, LCB_CONFIG_MCD_PORT);
713
858
  }
@@ -731,6 +876,18 @@ Server::~Server() {
731
876
  return;
732
877
  }
733
878
 
879
+ if (this->instance) {
880
+ unsigned ii;
881
+ mc_CMDQUEUE *cmdq = &this->instance->cmdq;
882
+ for (ii = 0; ii < cmdq->npipelines; ii++) {
883
+ lcb::Server *server = static_cast<lcb::Server*>(cmdq->pipelines[ii]);
884
+ if (server == this) {
885
+ cmdq->pipelines[ii] = NULL;
886
+ break;
887
+ }
888
+ }
889
+ }
890
+ this->instance = NULL;
734
891
  mcreq_pipeline_cleanup(this);
735
892
 
736
893
  if (io_timer) {