libcouchbase 1.2.8 → 1.3.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/README.md +16 -8
- data/ext/libcouchbase/CMakeLists.txt +34 -32
- data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
- data/ext/libcouchbase/cmake/configure +8 -26
- data/ext/libcouchbase/cmake/defs.mk.in +2 -2
- data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
- data/ext/libcouchbase/cmake/source_files.cmake +11 -2
- data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
- data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
- data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
- data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
- data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
- data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
- data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
- data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
- data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
- data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
- data/ext/libcouchbase/example/crypto/.gitignore +2 -0
- data/ext/libcouchbase/example/crypto/Makefile +13 -0
- data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
- data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
- data/ext/libcouchbase/example/tracing/.gitignore +2 -0
- data/ext/libcouchbase/example/tracing/Makefile +8 -0
- data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
- data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
- data/ext/libcouchbase/example/tracing/tracing.c +439 -0
- data/ext/libcouchbase/example/tracing/views.c +444 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
- data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
- data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
- data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
- data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
- data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
- data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
- data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
- data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
- data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
- data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
- data/ext/libcouchbase/src/auth-priv.h +36 -4
- data/ext/libcouchbase/src/auth.cc +66 -27
- data/ext/libcouchbase/src/bootstrap.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
- data/ext/libcouchbase/src/cbft.cc +48 -0
- data/ext/libcouchbase/src/cntl.cc +138 -2
- data/ext/libcouchbase/src/config_static.h +17 -0
- data/ext/libcouchbase/src/connspec.cc +54 -6
- data/ext/libcouchbase/src/connspec.h +9 -1
- data/ext/libcouchbase/src/crypto.cc +386 -0
- data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
- data/ext/libcouchbase/src/dump.cc +4 -0
- data/ext/libcouchbase/src/getconfig.cc +1 -2
- data/ext/libcouchbase/src/handler.cc +65 -27
- data/ext/libcouchbase/src/hostlist.cc +35 -7
- data/ext/libcouchbase/src/hostlist.h +7 -0
- data/ext/libcouchbase/src/http/http-priv.h +2 -0
- data/ext/libcouchbase/src/http/http.cc +77 -37
- data/ext/libcouchbase/src/http/http_io.cc +19 -2
- data/ext/libcouchbase/src/instance.cc +90 -17
- data/ext/libcouchbase/src/internal.h +5 -0
- data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
- data/ext/libcouchbase/src/lcbio/connect.h +27 -0
- data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
- data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
- data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
- data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
- data/ext/libcouchbase/src/lcbio/manager.h +2 -0
- data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
- data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
- data/ext/libcouchbase/src/logging.c +1 -1
- data/ext/libcouchbase/src/logging.h +2 -0
- data/ext/libcouchbase/src/mc/compress.cc +164 -0
- data/ext/libcouchbase/src/mc/compress.h +7 -12
- data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
- data/ext/libcouchbase/src/mc/mcreq.c +11 -1
- data/ext/libcouchbase/src/mc/mcreq.h +35 -4
- data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
- data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
- data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
- data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
- data/ext/libcouchbase/src/mctx-helper.h +11 -0
- data/ext/libcouchbase/src/metrics.cc +132 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
- data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
- data/ext/libcouchbase/src/newconfig.cc +9 -2
- data/ext/libcouchbase/src/operations/counter.cc +2 -1
- data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
- data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
- data/ext/libcouchbase/src/operations/durability.cc +24 -2
- data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
- data/ext/libcouchbase/src/operations/get.cc +4 -2
- data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
- data/ext/libcouchbase/src/operations/observe.cc +113 -62
- data/ext/libcouchbase/src/operations/ping.cc +246 -67
- data/ext/libcouchbase/src/operations/remove.cc +2 -1
- data/ext/libcouchbase/src/operations/store.cc +17 -14
- data/ext/libcouchbase/src/operations/touch.cc +3 -0
- data/ext/libcouchbase/src/packetutils.h +68 -4
- data/ext/libcouchbase/src/probes.d +132 -161
- data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
- data/ext/libcouchbase/src/retryq.cc +6 -2
- data/ext/libcouchbase/src/rnd.cc +68 -0
- data/ext/libcouchbase/src/rnd.h +39 -0
- data/ext/libcouchbase/src/settings.c +27 -0
- data/ext/libcouchbase/src/settings.h +67 -3
- data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
- data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
- data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
- data/ext/libcouchbase/src/trace.h +68 -61
- data/ext/libcouchbase/src/tracing/span.cc +289 -0
- data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
- data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
- data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
- data/ext/libcouchbase/src/utilities.c +5 -0
- data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
- data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
- data/ext/libcouchbase/src/views/docreq.cc +26 -1
- data/ext/libcouchbase/src/views/docreq.h +17 -0
- data/ext/libcouchbase/src/views/viewreq.cc +64 -1
- data/ext/libcouchbase/src/views/viewreq.h +21 -0
- data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
- data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
- data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
- data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
- data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
- data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
- data/ext/libcouchbase/tests/check-all.cc +6 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
- data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
- data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
- data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
- data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
- data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
- data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
- data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
- data/ext/libcouchbase/tools/cbc.cc +113 -8
- data/ext/libcouchbase/tools/common/histogram.cc +1 -0
- data/ext/libcouchbase/tools/common/options.cc +28 -1
- data/ext/libcouchbase/tools/common/options.h +5 -0
- data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
- data/ext/libcouchbase/tools/docgen/loc.h +5 -4
- data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
- data/lib/libcouchbase/n1ql.rb +6 -1
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/connection_spec.rb +6 -6
- metadata +38 -5
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
- data/ext/libcouchbase/src/mc/compress.c +0 -90
- data/ext/libcouchbase/tools/common/my_inttypes.h +0 -22
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
#include "mcreq.h"
|
|
19
|
+
#include "settings.h"
|
|
19
20
|
#ifndef LCB_MCCOMPRESS_H
|
|
20
21
|
#define LCB_MCCOMPRESS_H
|
|
21
22
|
|
|
@@ -28,11 +29,12 @@ extern "C" {
|
|
|
28
29
|
* @param pl The pipeline which hosts the packet
|
|
29
30
|
* @param pkt The packet which hosts the value
|
|
30
31
|
* @param vbuf The user input to be compressed
|
|
32
|
+
* @param settings The instance settings
|
|
33
|
+
* @param should_compress The pointer, which stores zero if the value is not compressed
|
|
31
34
|
* @return 0 if successful, nonzero on error.
|
|
32
35
|
*/
|
|
33
|
-
int
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
int mcreq_compress_value(mc_PIPELINE *pl, mc_PACKET *pkt, const lcb_VALBUF *vbuf, lcb_settings *settings,
|
|
37
|
+
int *should_compress);
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
40
|
* Inflate a compressed value
|
|
@@ -45,15 +47,8 @@ mcreq_compress_value(mc_PIPELINE *pl, mc_PACKET *pkt, const lcb_CONTIGBUF *vbuf)
|
|
|
45
47
|
* longer required.
|
|
46
48
|
* @return 0 if successful, nonzero on error.
|
|
47
49
|
*/
|
|
48
|
-
int
|
|
49
|
-
|
|
50
|
-
const void **bytes, lcb_SIZE *nbytes, void **freeptr);
|
|
51
|
-
|
|
52
|
-
#ifndef LCB_NO_SNAPPY
|
|
53
|
-
#define mcreq_compression_supported() 1
|
|
54
|
-
#else
|
|
55
|
-
#define mcreq_compression_supported() 0
|
|
56
|
-
#endif
|
|
50
|
+
int mcreq_inflate_value(const void *compressed, lcb_SIZE ncompressed, const void **bytes, lcb_SIZE *nbytes,
|
|
51
|
+
void **freeptr);
|
|
57
52
|
|
|
58
53
|
#ifdef __cplusplus
|
|
59
54
|
}
|
|
@@ -67,6 +67,11 @@ mcreq__pktflush_callback(void *p, nb_SIZE hint, void *arg)
|
|
|
67
67
|
if (pkt->flags & MCREQ_F_INVOKED) {
|
|
68
68
|
mcreq_packet_done(info->pl, pkt);
|
|
69
69
|
}
|
|
70
|
+
if (info->pl->metrics) {
|
|
71
|
+
info->pl->metrics->packets_sent++;
|
|
72
|
+
info->pl->metrics->packets_queued--;
|
|
73
|
+
info->pl->metrics->bytes_queued -= pktsize;
|
|
74
|
+
}
|
|
70
75
|
return pktsize;
|
|
71
76
|
}
|
|
72
77
|
|
|
@@ -89,7 +94,6 @@ mcreq_flush_done_ex(mc_PIPELINE *pl,
|
|
|
89
94
|
{
|
|
90
95
|
if (nflushed) {
|
|
91
96
|
mc__FLUSHINFO info = { pl, now };
|
|
92
|
-
|
|
93
97
|
netbuf_end_flush2(&pl->nbmgr, nflushed,
|
|
94
98
|
mcreq__pktflush_callback,
|
|
95
99
|
offsetof(mc_PACKET, sl_flushq), &info);
|
|
@@ -206,6 +206,7 @@ mcreq_enqueue_packet(mc_PIPELINE *pipeline, mc_PACKET *packet)
|
|
|
206
206
|
nb_SPAN *vspan = &packet->u_value.single;
|
|
207
207
|
sllist_append(&pipeline->requests, &packet->slnode);
|
|
208
208
|
netbuf_enqueue_span(&pipeline->nbmgr, &packet->kh_span);
|
|
209
|
+
MC_INCR_METRIC(pipeline, bytes_queued, packet->kh_span.size);
|
|
209
210
|
|
|
210
211
|
if (!(packet->flags & MCREQ_F_HASVALUE)) {
|
|
211
212
|
goto GT_ENQUEUE_PDU;
|
|
@@ -216,14 +217,17 @@ mcreq_enqueue_packet(mc_PIPELINE *pipeline, mc_PACKET *packet)
|
|
|
216
217
|
lcb_FRAGBUF *multi = &packet->u_value.multi;
|
|
217
218
|
for (ii = 0; ii < multi->niov; ii++) {
|
|
218
219
|
netbuf_enqueue(&pipeline->nbmgr, (nb_IOV *)multi->iov + ii);
|
|
220
|
+
MC_INCR_METRIC(pipeline, bytes_queued, multi->iov[ii].iov_len);
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
} else if (vspan->size) {
|
|
224
|
+
MC_INCR_METRIC(pipeline, bytes_queued, vspan->size);
|
|
222
225
|
netbuf_enqueue_span(&pipeline->nbmgr, vspan);
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
GT_ENQUEUE_PDU:
|
|
226
229
|
netbuf_pdu_enqueue(&pipeline->nbmgr, packet, offsetof(mc_PACKET, sl_flushq));
|
|
230
|
+
MC_INCR_METRIC(pipeline, packets_queued, 1);
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
void
|
|
@@ -275,6 +279,9 @@ mcreq_allocate_packet(mc_PIPELINE *pipeline)
|
|
|
275
279
|
ret->flags = 0;
|
|
276
280
|
ret->retries = 0;
|
|
277
281
|
ret->opaque = pipeline->parent->seq++;
|
|
282
|
+
#ifdef LCB_TRACING
|
|
283
|
+
ret->u_rdata.reqdata.span = NULL;
|
|
284
|
+
#endif
|
|
278
285
|
return ret;
|
|
279
286
|
}
|
|
280
287
|
|
|
@@ -568,6 +575,7 @@ mcreq_pipeline_init(mc_PIPELINE *pipeline)
|
|
|
568
575
|
/** Initialize request pool */
|
|
569
576
|
settings.data_basealloc = sizeof(mc_PACKET) * 32;
|
|
570
577
|
netbuf_init(&pipeline->reqpool, &settings);;
|
|
578
|
+
pipeline->metrics = NULL;
|
|
571
579
|
return 0;
|
|
572
580
|
}
|
|
573
581
|
|
|
@@ -866,8 +874,10 @@ do_fallback_flush(mc_PIPELINE *pipeline)
|
|
|
866
874
|
void
|
|
867
875
|
mcreq_set_fallback_handler(mc_CMDQUEUE *cq, mcreq_fallback_cb handler)
|
|
868
876
|
{
|
|
877
|
+
mc_FALLBACKPL *fallback;
|
|
869
878
|
assert(!cq->fallback);
|
|
870
|
-
|
|
879
|
+
fallback = calloc(1, sizeof (mc_FALLBACKPL));
|
|
880
|
+
cq->fallback = (mc_PIPELINE *)fallback;
|
|
871
881
|
mcreq_pipeline_init(cq->fallback);
|
|
872
882
|
cq->fallback->parent = cq;
|
|
873
883
|
cq->fallback->index = cq->npipelines;
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
#include <libcouchbase/api3.h>
|
|
23
23
|
#include <libcouchbase/vbucket.h>
|
|
24
24
|
#include <memcached/protocol_binary.h>
|
|
25
|
+
#include <libcouchbase/metrics.h>
|
|
25
26
|
#include "netbuf/netbuf.h"
|
|
26
27
|
#include "sllist.h"
|
|
27
28
|
#include "config.h"
|
|
@@ -141,9 +142,17 @@ extern "C" {
|
|
|
141
142
|
#define MCREQ_PKT_BASESIZE 24
|
|
142
143
|
|
|
143
144
|
/** @brief Embedded user data for a simple request. */
|
|
144
|
-
typedef struct {
|
|
145
|
+
typedef struct mc_REQDATA {
|
|
145
146
|
const void *cookie; /**< User pointer to place in callbacks */
|
|
146
147
|
hrtime_t start; /**< Time of the initial request. Used for timeouts */
|
|
148
|
+
/**
|
|
149
|
+
* Time when dispatching response has begun for the command.
|
|
150
|
+
* Used for metrics/tracing. Might be zero, when tracing is not enabled.
|
|
151
|
+
*/
|
|
152
|
+
hrtime_t dispatch;
|
|
153
|
+
#ifdef LCB_TRACING
|
|
154
|
+
lcbtrace_SPAN *span;
|
|
155
|
+
#endif
|
|
147
156
|
} mc_REQDATA;
|
|
148
157
|
|
|
149
158
|
struct mc_packet_st;
|
|
@@ -182,12 +191,24 @@ typedef struct {
|
|
|
182
191
|
typedef struct mc_REQDATAEX {
|
|
183
192
|
const void *cookie; /**< User data */
|
|
184
193
|
hrtime_t start; /**< Start time */
|
|
194
|
+
/**
|
|
195
|
+
* Time when dispatching response has begun for the command.
|
|
196
|
+
* Used for metrics/tracing. Might be zero, when tracing is not enabled.
|
|
197
|
+
*/
|
|
198
|
+
hrtime_t dispatch;
|
|
199
|
+
#ifdef LCB_TRACING
|
|
200
|
+
lcbtrace_SPAN *span;
|
|
201
|
+
#endif
|
|
185
202
|
const mc_REQDATAPROCS *procs; /**< Common routines for the packet */
|
|
186
203
|
|
|
187
204
|
#ifdef __cplusplus
|
|
188
|
-
mc_REQDATAEX(const void *cookie_,
|
|
189
|
-
|
|
190
|
-
|
|
205
|
+
mc_REQDATAEX(const void *cookie_, const mc_REQDATAPROCS &procs_, hrtime_t start_)
|
|
206
|
+
: cookie(cookie_), start(start_), dispatch(0),
|
|
207
|
+
#ifdef LCB_TRACING
|
|
208
|
+
span(NULL),
|
|
209
|
+
#endif
|
|
210
|
+
procs(&procs_)
|
|
211
|
+
{
|
|
191
212
|
}
|
|
192
213
|
#endif
|
|
193
214
|
} mc_REQDATAEX;
|
|
@@ -400,6 +421,9 @@ typedef struct mc_pipeline_st {
|
|
|
400
421
|
|
|
401
422
|
/** Allocator for packet structures */
|
|
402
423
|
nb_MGR reqpool;
|
|
424
|
+
|
|
425
|
+
/** Optional metrics structure for server */
|
|
426
|
+
struct lcb_SERVERMETRICS_st *metrics;
|
|
403
427
|
} mc_PIPELINE;
|
|
404
428
|
|
|
405
429
|
typedef struct mc_cmdqueue_st {
|
|
@@ -976,6 +1000,13 @@ mcreq_dump_chain(const mc_PIPELINE *pipeline, FILE *fp, mcreq_payload_dump_fn du
|
|
|
976
1000
|
SLLIST_IS_EMPTY(&(pipeline)->requests) ? NULL : \
|
|
977
1001
|
SLLIST_ITEM(SLLIST_FIRST(&(pipeline)->requests), mc_PACKET, slnode)
|
|
978
1002
|
|
|
1003
|
+
/* Increment a metric */
|
|
1004
|
+
#define MC_INCR_METRIC(pipeline, metric, amount) do { \
|
|
1005
|
+
if ((pipeline)->metrics) { \
|
|
1006
|
+
(pipeline)->metrics->metric += amount; \
|
|
1007
|
+
} \
|
|
1008
|
+
} while (0)
|
|
1009
|
+
|
|
979
1010
|
/**@}*/
|
|
980
1011
|
|
|
981
1012
|
#ifdef __cplusplus
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
#define LOGARGS(c, lvl) (c)->settings, "server", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
29
29
|
#define LOGARGS_T(lvl) LOGARGS(this, lvl)
|
|
30
30
|
|
|
31
|
-
#define LOGFMT "
|
|
31
|
+
#define LOGFMT CTX_LOGFMT_PRE ",SRV=%p,IX=%d) "
|
|
32
32
|
#define PKTFMT "OP=0x%x, RC=0x%x, SEQ=%u"
|
|
33
33
|
#define PKTARGS(pkt) (pkt).opcode(), (pkt).status(), (pkt).opaque()
|
|
34
34
|
|
|
35
|
-
#define LOGID(server)
|
|
35
|
+
#define LOGID(server) CTX_LOGID(server->connctx), (void *)server, server->index
|
|
36
36
|
#define LOGID_T() LOGID(this)
|
|
37
37
|
|
|
38
38
|
#define MCREQ_MAXIOV 32
|
|
@@ -125,6 +125,8 @@ Server::handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt)
|
|
|
125
125
|
lcb::clconfig::Provider *cccp =
|
|
126
126
|
instance->confmon->get_provider(lcb::clconfig::CLCONFIG_CCCP);
|
|
127
127
|
|
|
128
|
+
MC_INCR_METRIC(this, packets_nmv, 1);
|
|
129
|
+
|
|
128
130
|
mcreq_read_hdr(oldpkt, &hdr);
|
|
129
131
|
vbid = ntohs(hdr.request.vbucket);
|
|
130
132
|
lcb_log(LOGARGS_T(WARN), LOGFMT "NOT_MY_VBUCKET. Packet=%p (S=%u). VBID=%u", LOGID_T(), (void*)oldpkt, oldpkt->opaque, vbid);
|
|
@@ -132,8 +134,8 @@ Server::handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt)
|
|
|
132
134
|
/* Notify of new map */
|
|
133
135
|
lcb_vbguess_remap(instance, vbid, index);
|
|
134
136
|
|
|
135
|
-
if (resinfo.
|
|
136
|
-
std::string s(resinfo.
|
|
137
|
+
if (resinfo.vallen() && cccp->enabled) {
|
|
138
|
+
std::string s(resinfo.value(), resinfo.vallen());
|
|
137
139
|
err = lcb::clconfig::cccp_update(cccp, curhost->host, s.c_str());
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -334,6 +336,8 @@ Server::try_read(lcbio_CTX *ctx, rdb_IOROPE *ior)
|
|
|
334
336
|
RETURN_NEED_MORE(pktsize)
|
|
335
337
|
}
|
|
336
338
|
|
|
339
|
+
MC_INCR_METRIC(this, packets_read, 1);
|
|
340
|
+
|
|
337
341
|
/* copy bytes into the info structure */
|
|
338
342
|
rdb_copyread(ior, mcresp.hdrbytes(), mcresp.hdrsize());
|
|
339
343
|
|
|
@@ -352,6 +356,7 @@ Server::try_read(lcbio_CTX *ctx, rdb_IOROPE *ior)
|
|
|
352
356
|
}
|
|
353
357
|
|
|
354
358
|
if (!request) {
|
|
359
|
+
MC_INCR_METRIC(this, packets_ownerless, 1);
|
|
355
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());
|
|
356
361
|
rdb_consumed(ior, pktsize);
|
|
357
362
|
return PKT_READ_COMPLETE;
|
|
@@ -494,6 +499,9 @@ void Server::purge_single(mc_PACKET *pkt, lcb_error_t err) {
|
|
|
494
499
|
hdr.request.opaque,
|
|
495
500
|
PROTOCOL_BINARY_RESPONSE_EINVAL);
|
|
496
501
|
|
|
502
|
+
#ifdef LCB_TRACING
|
|
503
|
+
lcbtrace_span_set_orphaned(MCREQ_PKT_RDATA(pkt)->span, true);
|
|
504
|
+
#endif
|
|
497
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));
|
|
498
506
|
int rv = mcreq_dispatch_response(this, pkt, &resp, err);
|
|
499
507
|
lcb_assert(rv == 0);
|
|
@@ -514,6 +522,7 @@ Server::purge(lcb_error_t error, hrtime_t thresh, hrtime_t *next,
|
|
|
514
522
|
affected = -1;
|
|
515
523
|
}
|
|
516
524
|
|
|
525
|
+
MC_INCR_METRIC(this, packets_errored, affected);
|
|
517
526
|
if (policy == REFRESH_NEVER) {
|
|
518
527
|
return affected;
|
|
519
528
|
}
|
|
@@ -569,6 +578,7 @@ void Server::io_timeout()
|
|
|
569
578
|
int npurged = purge(LCB_ETIMEDOUT, min_valid, &next_ns,
|
|
570
579
|
Server::REFRESH_ONFAILED);
|
|
571
580
|
if (npurged) {
|
|
581
|
+
MC_INCR_METRIC(this, packets_timeout, npurged);
|
|
572
582
|
lcb_log(LOGARGS_T(ERR), LOGFMT "Server timed out. Some commands have failed", LOGID_T());
|
|
573
583
|
}
|
|
574
584
|
|
|
@@ -619,6 +629,7 @@ Server::handle_connected(lcbio_SOCKET *sock, lcb_error_t err, lcbio_OSERR syserr
|
|
|
619
629
|
|
|
620
630
|
if (err != LCB_SUCCESS) {
|
|
621
631
|
lcb_log(LOGARGS_T(ERR), LOGFMT "Connection attempt failed. Received %s from libcouchbase, received %d from operating system", LOGID_T(), lcb_strerror_short(err), syserr);
|
|
632
|
+
MC_INCR_METRIC(this, iometrics.io_error, 1);
|
|
622
633
|
if (!maybe_reconnect_on_fake_timeout(err)) {
|
|
623
634
|
socket_failed(err);
|
|
624
635
|
}
|
|
@@ -626,6 +637,9 @@ Server::handle_connected(lcbio_SOCKET *sock, lcb_error_t err, lcbio_OSERR syserr
|
|
|
626
637
|
}
|
|
627
638
|
|
|
628
639
|
lcb_assert(sock);
|
|
640
|
+
if (metrics) {
|
|
641
|
+
lcbio_set_metrics(sock, &metrics->iometrics);
|
|
642
|
+
}
|
|
629
643
|
|
|
630
644
|
/** Do we need sasl? */
|
|
631
645
|
SessionInfo* sessinfo = SessionInfo::get(sock);
|
|
@@ -635,7 +649,8 @@ Server::handle_connected(lcbio_SOCKET *sock, lcb_error_t err, lcbio_OSERR syserr
|
|
|
635
649
|
sock, settings, default_timeout(), on_connected, this);
|
|
636
650
|
return;
|
|
637
651
|
} else {
|
|
638
|
-
|
|
652
|
+
jsonsupport = sessinfo->has_feature(PROTOCOL_BINARY_FEATURE_JSON);
|
|
653
|
+
compsupport = sessinfo->has_feature(PROTOCOL_BINARY_FEATURE_SNAPPY);
|
|
639
654
|
mutation_tokens = sessinfo->has_feature(PROTOCOL_BINARY_FEATURE_MUTATION_SEQNO);
|
|
640
655
|
}
|
|
641
656
|
|
|
@@ -646,6 +661,7 @@ Server::handle_connected(lcbio_SOCKET *sock, lcb_error_t err, lcbio_OSERR syserr
|
|
|
646
661
|
procs.cb_flush_ready = on_flush_ready;
|
|
647
662
|
connctx = lcbio_ctx_new(sock, this, &procs);
|
|
648
663
|
connctx->subsys = "memcached";
|
|
664
|
+
sock->service = LCBIO_SERVICE_KV;
|
|
649
665
|
flush_start = (mcreq_flushstart_fn)mcserver_flush;
|
|
650
666
|
|
|
651
667
|
uint32_t tmo = next_timeout();
|
|
@@ -675,6 +691,7 @@ Server::Server(lcb_t instance_, int ix)
|
|
|
675
691
|
instance(instance_),
|
|
676
692
|
settings(lcb_settings_ref2(instance_->settings)),
|
|
677
693
|
compsupport(0),
|
|
694
|
+
jsonsupport(0),
|
|
678
695
|
mutation_tokens(0),
|
|
679
696
|
connctx(NULL),
|
|
680
697
|
curhost(new lcb_host_t())
|
|
@@ -694,11 +711,17 @@ Server::Server(lcb_t instance_, int ix)
|
|
|
694
711
|
if (datahost) {
|
|
695
712
|
lcb_host_parsez(curhost, datahost, LCB_CONFIG_MCD_PORT);
|
|
696
713
|
}
|
|
714
|
+
|
|
715
|
+
if (settings->metrics) {
|
|
716
|
+
/** Allocate / reinitialize the metrics here */
|
|
717
|
+
metrics = lcb_metrics_getserver(settings->metrics, curhost->host, curhost->port, 1);
|
|
718
|
+
lcb_metrics_reset_pipeline_gauges(metrics);
|
|
719
|
+
}
|
|
697
720
|
}
|
|
698
721
|
|
|
699
722
|
Server::Server()
|
|
700
723
|
: state(S_TEMPORARY),
|
|
701
|
-
io_timer(NULL), instance(NULL), settings(NULL), compsupport(0),
|
|
724
|
+
io_timer(NULL), instance(NULL), settings(NULL), compsupport(0), jsonsupport(0),
|
|
702
725
|
mutation_tokens(0), connctx(NULL), connreq(NULL), curhost(NULL)
|
|
703
726
|
{
|
|
704
727
|
}
|
|
@@ -829,7 +852,7 @@ Server::finalize_errored_ctx()
|
|
|
829
852
|
return;
|
|
830
853
|
}
|
|
831
854
|
|
|
832
|
-
lcb_log(LOGARGS_T(DEBUG), LOGFMT "Finalizing
|
|
855
|
+
lcb_log(LOGARGS_T(DEBUG), LOGFMT "Finalizing context", LOGID_T());
|
|
833
856
|
|
|
834
857
|
/* Always close the existing context. */
|
|
835
858
|
lcbio_ctx_close(connctx, close_cb, NULL);
|
|
@@ -110,6 +110,10 @@ public:
|
|
|
110
110
|
return compsupport;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
bool supports_json() const {
|
|
114
|
+
return jsonsupport;
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
bool is_connected() const {
|
|
114
118
|
return connctx != NULL;
|
|
115
119
|
}
|
|
@@ -200,6 +204,9 @@ public:
|
|
|
200
204
|
/** Whether compression is supported */
|
|
201
205
|
short compsupport;
|
|
202
206
|
|
|
207
|
+
/** Whether JSON datatype is supported */
|
|
208
|
+
short jsonsupport;
|
|
209
|
+
|
|
203
210
|
/** Whether extended 'UUID' and 'seqno' are available for each mutation */
|
|
204
211
|
short mutation_tokens;
|
|
205
212
|
|
|
@@ -37,12 +37,12 @@ using namespace lcb;
|
|
|
37
37
|
#define LOGARGS(ctx, lvl) ctx->settings, "negotiation", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
38
38
|
static void cleanup_negotiated(SessionInfo* info);
|
|
39
39
|
static void handle_ioerr(lcbio_CTX *ctx, lcb_error_t err);
|
|
40
|
-
#define SESSREQ_LOGFMT "<%s:%s> (SASLREQ=%p) "
|
|
41
40
|
|
|
41
|
+
#define LOGFMT CTX_LOGFMT_PRE ",SASLREQ=%p) "
|
|
42
|
+
#define LOGID(s) CTX_LOGID(s->ctx), (void *)s
|
|
42
43
|
|
|
43
44
|
static void timeout_handler(void *arg);
|
|
44
45
|
|
|
45
|
-
#define SESSREQ_LOGID(s) get_ctx_host(s->ctx), get_ctx_port(s->ctx), (void*)s
|
|
46
46
|
|
|
47
47
|
static void
|
|
48
48
|
close_cb(lcbio_SOCKET *s, int reusable, void *arg)
|
|
@@ -67,8 +67,10 @@ public:
|
|
|
67
67
|
const lcb::Authenticator& auth);
|
|
68
68
|
void start(lcbio_SOCKET *sock);
|
|
69
69
|
void send_list_mechs();
|
|
70
|
+
std::string generate_agent_json();
|
|
70
71
|
bool send_hello();
|
|
71
72
|
bool send_step(const lcb::MemcachedResponse& packet);
|
|
73
|
+
bool check_auth(const lcb::MemcachedResponse& packet);
|
|
72
74
|
bool read_hello(const lcb::MemcachedResponse& packet);
|
|
73
75
|
void send_auth(const char *sasl_data, unsigned ndata);
|
|
74
76
|
void handle_read(lcbio_CTX *ioctx);
|
|
@@ -144,12 +146,12 @@ public:
|
|
|
144
146
|
}
|
|
145
147
|
emsg << "context: \"" << err_ctx << "\"";
|
|
146
148
|
}
|
|
147
|
-
lcb_log(LOGARGS(this, ERR),
|
|
148
|
-
|
|
149
|
+
lcb_log(LOGARGS(this, ERR), LOGFMT "Error: 0x%x, %s (%s)",
|
|
150
|
+
LOGID(this), error, msg, emsg.str().c_str());
|
|
149
151
|
free(err_ref);
|
|
150
152
|
free(err_ctx);
|
|
151
153
|
} else {
|
|
152
|
-
lcb_log(LOGARGS(this, ERR),
|
|
154
|
+
lcb_log(LOGARGS(this, ERR), LOGFMT "Error: 0x%x, %s", LOGID(this), error, msg);
|
|
153
155
|
}
|
|
154
156
|
if (last_err == LCB_SUCCESS) {
|
|
155
157
|
last_err = error;
|
|
@@ -236,8 +238,8 @@ SessionRequestImpl::setup(const lcbio_NAMEINFO& nistrs, const lcb_host_t& host,
|
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
// Get the credentials
|
|
239
|
-
username = auth.username_for(settings->bucket);
|
|
240
|
-
const std::string
|
|
241
|
+
username = auth.username_for(host.host, host.port, settings->bucket);
|
|
242
|
+
const std::string pass = auth.password_for(host.host, host.port, settings->bucket);
|
|
241
243
|
|
|
242
244
|
if (!pass.empty()) {
|
|
243
245
|
size_t maxlen = sizeof(u_auth.buffer) - offsetof(cbsasl_secret_t, data);
|
|
@@ -273,6 +275,13 @@ SessionRequestImpl::set_chosen_mech(std::string& mechlist,
|
|
|
273
275
|
const char **data, unsigned int *ndata)
|
|
274
276
|
{
|
|
275
277
|
cbsasl_error_t saslerr;
|
|
278
|
+
int allow_scram_sha = 0;
|
|
279
|
+
|
|
280
|
+
if (mechlist.empty()) {
|
|
281
|
+
lcb_log(LOGARGS(this, WARN), LOGFMT "Server does not support SASL (no mechanisms supported)", LOGID(this));
|
|
282
|
+
return MECH_NOT_NEEDED;
|
|
283
|
+
}
|
|
284
|
+
|
|
276
285
|
if (settings->sasl_mech_force) {
|
|
277
286
|
char *forcemech = settings->sasl_mech_force;
|
|
278
287
|
if (mechlist.find(forcemech) == std::string::npos) {
|
|
@@ -281,21 +290,22 @@ SessionRequestImpl::set_chosen_mech(std::string& mechlist,
|
|
|
281
290
|
return MECH_UNAVAILABLE;
|
|
282
291
|
}
|
|
283
292
|
mechlist.assign(forcemech);
|
|
293
|
+
if (memcmp(forcemech, "SCRAM-SHA", sizeof("SCRAM-SHA") - 1) == 0) {
|
|
294
|
+
allow_scram_sha = 1;
|
|
295
|
+
}
|
|
284
296
|
}
|
|
285
297
|
|
|
286
298
|
const char *chosenmech;
|
|
287
|
-
saslerr = cbsasl_client_start(sasl_client, mechlist.c_str(),
|
|
288
|
-
NULL, data, ndata, &chosenmech);
|
|
299
|
+
saslerr = cbsasl_client_start(sasl_client, mechlist.c_str(), NULL, data, ndata, &chosenmech, allow_scram_sha);
|
|
289
300
|
switch (saslerr) {
|
|
290
301
|
case SASL_OK:
|
|
291
302
|
info->mech.assign(chosenmech);
|
|
292
303
|
return MECH_OK;
|
|
293
304
|
case SASL_NOMECH:
|
|
294
|
-
lcb_log(LOGARGS(this,
|
|
295
|
-
return
|
|
296
|
-
break;
|
|
305
|
+
lcb_log(LOGARGS(this, WARN), LOGFMT "Server does not support SASL (no mechanisms supported)", LOGID(this));
|
|
306
|
+
return MECH_UNAVAILABLE;
|
|
297
307
|
default:
|
|
298
|
-
lcb_log(LOGARGS(this,
|
|
308
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "cbsasl_client_start returned %d", LOGID(this), saslerr);
|
|
299
309
|
set_error(LCB_EINTERNAL, "Couldn't start SASL client");
|
|
300
310
|
return MECH_UNAVAILABLE;
|
|
301
311
|
}
|
|
@@ -323,8 +333,7 @@ SessionRequestImpl::send_step(const lcb::MemcachedResponse& packet)
|
|
|
323
333
|
const char *step_data;
|
|
324
334
|
unsigned int ndata;
|
|
325
335
|
|
|
326
|
-
saslerr = cbsasl_client_step(sasl_client,
|
|
327
|
-
packet.body<const char*>(), packet.bodylen(), NULL, &step_data, &ndata);
|
|
336
|
+
saslerr = cbsasl_client_step(sasl_client, packet.value(), packet.vallen(), NULL, &step_data, &ndata);
|
|
328
337
|
|
|
329
338
|
if (saslerr != SASL_CONTINUE) {
|
|
330
339
|
set_error(LCB_EINTERNAL, "Unable to perform SASL STEP");
|
|
@@ -340,8 +349,50 @@ SessionRequestImpl::send_step(const lcb::MemcachedResponse& packet)
|
|
|
340
349
|
return true;
|
|
341
350
|
}
|
|
342
351
|
|
|
343
|
-
|
|
344
|
-
|
|
352
|
+
std::string
|
|
353
|
+
SessionRequestImpl::generate_agent_json()
|
|
354
|
+
{
|
|
355
|
+
std::string client_string(LCB_CLIENT_ID);
|
|
356
|
+
if (settings->client_string) {
|
|
357
|
+
client_string += " ";
|
|
358
|
+
client_string += settings->client_string;
|
|
359
|
+
}
|
|
360
|
+
if (client_string.size() > 200) {
|
|
361
|
+
client_string.resize(200);
|
|
362
|
+
}
|
|
363
|
+
char id[34] = {};
|
|
364
|
+
snprintf(id, sizeof(id), "%016" PRIx64 "/%016" PRIx64, (lcb_U64)settings->iid, ctx->sock->id);
|
|
365
|
+
|
|
366
|
+
Json::Value ua;
|
|
367
|
+
ua["a"] = client_string;
|
|
368
|
+
ua["i"] = id;
|
|
369
|
+
Json::FastWriter w;
|
|
370
|
+
std::string res = w.write(ua);
|
|
371
|
+
if (res[res.size() - 1] == '\n') {
|
|
372
|
+
res.resize(res.size() - 1);
|
|
373
|
+
}
|
|
374
|
+
return res;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Final step for SASL authentication: in SCRAM-SHA mechanisms,
|
|
379
|
+
* we have to validate the server signature returned in the final
|
|
380
|
+
* message.
|
|
381
|
+
*/
|
|
382
|
+
bool
|
|
383
|
+
SessionRequestImpl::check_auth(const lcb::MemcachedResponse& packet)
|
|
384
|
+
{
|
|
385
|
+
cbsasl_error_t saslerr;
|
|
386
|
+
|
|
387
|
+
saslerr = cbsasl_client_check(sasl_client,
|
|
388
|
+
packet.body<const char*>(), packet.bodylen());
|
|
389
|
+
|
|
390
|
+
if (saslerr != SASL_OK) {
|
|
391
|
+
set_error(LCB_AUTH_ERROR, "Invalid SASL check");
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
345
396
|
|
|
346
397
|
bool
|
|
347
398
|
SessionRequestImpl::send_hello()
|
|
@@ -351,6 +402,7 @@ SessionRequestImpl::send_hello()
|
|
|
351
402
|
unsigned nfeatures = 0;
|
|
352
403
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TLS;
|
|
353
404
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XATTR;
|
|
405
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_JSON;
|
|
354
406
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_SELECT_BUCKET;
|
|
355
407
|
if (settings->use_errmap) {
|
|
356
408
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XERROR;
|
|
@@ -358,38 +410,29 @@ SessionRequestImpl::send_hello()
|
|
|
358
410
|
if (settings->tcp_nodelay) {
|
|
359
411
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TCPNODELAY;
|
|
360
412
|
}
|
|
361
|
-
|
|
362
|
-
#ifndef LCB_NO_SNAPPY
|
|
363
413
|
if (settings->compressopts != LCB_COMPRESS_NONE) {
|
|
364
|
-
features[nfeatures++] =
|
|
414
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_SNAPPY;
|
|
365
415
|
}
|
|
366
|
-
#endif
|
|
367
|
-
|
|
368
416
|
if (settings->fetch_mutation_tokens) {
|
|
369
417
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_MUTATION_SEQNO;
|
|
370
418
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (settings->client_string) {
|
|
377
|
-
client_string.assign(LCB_HELLO_DEFL_STRING);
|
|
378
|
-
client_string += ", ";
|
|
379
|
-
client_string += settings->client_string;
|
|
380
|
-
|
|
381
|
-
clistr = client_string.c_str();
|
|
382
|
-
nclistr = client_string.size();
|
|
419
|
+
if (settings->use_collections) {
|
|
420
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_COLLECTIONS;
|
|
421
|
+
}
|
|
422
|
+
if (settings->use_tracing) {
|
|
423
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TRACING;
|
|
383
424
|
}
|
|
384
425
|
|
|
426
|
+
std::string agent = generate_agent_json();
|
|
385
427
|
lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_HELLO);
|
|
386
|
-
hdr.sizes(0,
|
|
387
|
-
|
|
428
|
+
hdr.sizes(0, agent.size(), (sizeof features[0]) * nfeatures);
|
|
388
429
|
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
|
389
|
-
lcbio_ctx_put(ctx,
|
|
430
|
+
lcbio_ctx_put(ctx, agent.c_str(), agent.size());
|
|
431
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "HELLO identificator: %.*s", LOGID(this), (int)agent.size(), agent.c_str());
|
|
390
432
|
for (size_t ii = 0; ii < nfeatures; ii++) {
|
|
391
433
|
lcb_U16 tmp = htons(features[ii]);
|
|
392
434
|
lcbio_ctx_put(ctx, &tmp, sizeof tmp);
|
|
435
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Request feature: 0x%x (%s)", LOGID(this), features[ii], protocol_feature_2_text(features[ii]));
|
|
393
436
|
}
|
|
394
437
|
|
|
395
438
|
lcbio_ctx_rwant(ctx, 24);
|
|
@@ -409,13 +452,13 @@ SessionRequestImpl::read_hello(const lcb::MemcachedResponse& resp)
|
|
|
409
452
|
{
|
|
410
453
|
/* some caps */
|
|
411
454
|
const char *cur;
|
|
412
|
-
const char *payload = resp.
|
|
413
|
-
const char *limit = payload + resp.
|
|
455
|
+
const char *payload = resp.value();
|
|
456
|
+
const char *limit = payload + resp.vallen();
|
|
414
457
|
for (cur = payload; cur < limit; cur += 2) {
|
|
415
458
|
lcb_U16 tmp;
|
|
416
459
|
memcpy(&tmp, cur, sizeof(tmp));
|
|
417
460
|
tmp = ntohs(tmp);
|
|
418
|
-
lcb_log(LOGARGS(this, DEBUG),
|
|
461
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Server supports feature: 0x%x (%s)", LOGID(this), tmp, protocol_feature_2_text(tmp));
|
|
419
462
|
info->server_features.push_back(tmp);
|
|
420
463
|
}
|
|
421
464
|
return true;
|
|
@@ -442,8 +485,7 @@ SessionRequestImpl::update_errmap(const lcb::MemcachedResponse& resp)
|
|
|
442
485
|
|
|
443
486
|
std::string errmsg;
|
|
444
487
|
ErrorMap& mm = *settings->errmap;
|
|
445
|
-
ErrorMap::ParseStatus status = mm.parse(
|
|
446
|
-
resp.body<const char*>(), resp.bodylen(), errmsg);
|
|
488
|
+
ErrorMap::ParseStatus status = mm.parse(resp.value(), resp.vallen(), errmsg);
|
|
447
489
|
|
|
448
490
|
if (status != ErrorMap::UPDATED && status != ErrorMap::NOT_UPDATED) {
|
|
449
491
|
errmsg = "Couldn't update error map: " + errmsg;
|
|
@@ -464,12 +506,12 @@ SessionRequestImpl::maybe_select_bucket() {
|
|
|
464
506
|
}
|
|
465
507
|
|
|
466
508
|
if (!settings->select_bucket) {
|
|
467
|
-
lcb_log(LOGARGS(this, WARN),
|
|
509
|
+
lcb_log(LOGARGS(this, WARN), LOGFMT "SELECT_BUCKET Disabled by application", LOGID(this));
|
|
468
510
|
return false;
|
|
469
511
|
}
|
|
470
512
|
|
|
471
513
|
// send the SELECT_BUCKET command:
|
|
472
|
-
lcb_log(LOGARGS(this,
|
|
514
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Sending SELECT_BUCKET", LOGID(this));
|
|
473
515
|
lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SELECT_BUCKET);
|
|
474
516
|
req.sizes(0, strlen(settings->bucket), 0);
|
|
475
517
|
lcbio_ctx_put(ctx, req.data(), req.size());
|
|
@@ -507,7 +549,7 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
507
549
|
case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: {
|
|
508
550
|
const char *mechlist_data;
|
|
509
551
|
unsigned int nmechlist_data;
|
|
510
|
-
std::string mechs(resp.
|
|
552
|
+
std::string mechs(resp.value(), resp.vallen());
|
|
511
553
|
|
|
512
554
|
MechStatus mechrc = set_chosen_mech(mechs, &mechlist_data, &nmechlist_data);
|
|
513
555
|
if (mechrc == MECH_OK) {
|
|
@@ -534,10 +576,10 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
534
576
|
}
|
|
535
577
|
|
|
536
578
|
case PROTOCOL_BINARY_CMD_SASL_STEP: {
|
|
537
|
-
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
579
|
+
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS && check_auth(resp)) {
|
|
538
580
|
completed = !maybe_select_bucket();
|
|
539
581
|
} else {
|
|
540
|
-
lcb_log(LOGARGS(this, WARN),
|
|
582
|
+
lcb_log(LOGARGS(this, WARN), LOGFMT "SASL auth failed with STATUS=0x%x", LOGID(this), status);
|
|
541
583
|
set_error(LCB_AUTH_ERROR, "SASL Step failed", &resp);
|
|
542
584
|
}
|
|
543
585
|
break;
|
|
@@ -550,9 +592,9 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
550
592
|
break;
|
|
551
593
|
}
|
|
552
594
|
} else if (isUnsupported(status)) {
|
|
553
|
-
lcb_log(LOGARGS(this, DEBUG),
|
|
595
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Server does not support HELLO", LOGID(this));
|
|
554
596
|
} else {
|
|
555
|
-
lcb_log(LOGARGS(this, ERROR),
|
|
597
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for HELLO", LOGID(this), status);
|
|
556
598
|
set_error(LCB_PROTOCOL_ERROR, "Hello response unexpected", &resp);
|
|
557
599
|
break;
|
|
558
600
|
}
|
|
@@ -560,11 +602,15 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
560
602
|
if (info->has_feature(PROTOCOL_BINARY_FEATURE_XERROR)) {
|
|
561
603
|
request_errmap();
|
|
562
604
|
} else {
|
|
563
|
-
lcb_log(LOGARGS(this, TRACE),
|
|
605
|
+
lcb_log(LOGARGS(this, TRACE), LOGFMT "GET_ERRORMAP unsupported/disabled", LOGID(this));
|
|
564
606
|
}
|
|
565
607
|
|
|
566
|
-
|
|
567
|
-
|
|
608
|
+
if (settings->keypath) {
|
|
609
|
+
completed = !maybe_select_bucket();
|
|
610
|
+
} else {
|
|
611
|
+
// In any event, it's also time to send the LIST_MECHS request
|
|
612
|
+
send_list_mechs();
|
|
613
|
+
}
|
|
568
614
|
break;
|
|
569
615
|
}
|
|
570
616
|
|
|
@@ -573,9 +619,9 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
573
619
|
if (!update_errmap(resp)) {
|
|
574
620
|
}
|
|
575
621
|
} else if (isUnsupported(status)) {
|
|
576
|
-
lcb_log(LOGARGS(this, DEBUG),
|
|
622
|
+
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Server does not support GET_ERRMAP (0x%x)", LOGID(this), status);
|
|
577
623
|
} else {
|
|
578
|
-
lcb_log(LOGARGS(this, ERROR),
|
|
624
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for GET_ERRMAP", LOGID(this), status);
|
|
579
625
|
set_error(LCB_PROTOCOL_ERROR, "GET_ERRMAP response unexpected", &resp);
|
|
580
626
|
}
|
|
581
627
|
// Note, there is no explicit state transition here. LIST_MECHS is
|
|
@@ -589,14 +635,14 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
589
635
|
} else if (status == PROTOCOL_BINARY_RESPONSE_EACCESS) {
|
|
590
636
|
set_error(LCB_AUTH_ERROR, "Provided credentials not allowed for bucket", &resp);
|
|
591
637
|
} else {
|
|
592
|
-
lcb_log(LOGARGS(this, ERROR),
|
|
638
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET", LOGID(this), status);
|
|
593
639
|
set_error(LCB_PROTOCOL_ERROR, "Other auth error", &resp);
|
|
594
640
|
}
|
|
595
641
|
break;
|
|
596
642
|
}
|
|
597
643
|
|
|
598
644
|
default: {
|
|
599
|
-
lcb_log(LOGARGS(this, ERROR),
|
|
645
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", LOGID(this), resp.opcode(), resp.status());
|
|
600
646
|
set_error(LCB_NOT_SUPPORTED, "Received unknown response", &resp);
|
|
601
647
|
break;
|
|
602
648
|
}
|
|
@@ -658,7 +704,7 @@ SessionRequestImpl::start(lcbio_SOCKET *sock) {
|
|
|
658
704
|
if (settings->send_hello) {
|
|
659
705
|
send_hello();
|
|
660
706
|
} else {
|
|
661
|
-
lcb_log(LOGARGS(this,
|
|
707
|
+
lcb_log(LOGARGS(this, WARN), LOGFMT "HELLO negotiation disabled by user", LOGID(this));
|
|
662
708
|
send_list_mechs();
|
|
663
709
|
}
|
|
664
710
|
LCBIO_CTX_RSCHEDULE(ctx, 24);
|