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
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2018 Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is an example of using crypto API of libcouchbase. The implementation should not be considered as production
|
|
20
|
+
* ready, because it uses hardcoded keys, insecure memory allocation, copying and comparison. Consult documentation of
|
|
21
|
+
* your crypto library on how to properly work with keys and buffers.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#include <stdlib.h>
|
|
25
|
+
#include <string.h>
|
|
26
|
+
#include "openssl_symmetric_provider.h"
|
|
27
|
+
|
|
28
|
+
#include <openssl/ssl.h>
|
|
29
|
+
#include <openssl/conf.h>
|
|
30
|
+
#include <openssl/evp.h>
|
|
31
|
+
#include <openssl/err.h>
|
|
32
|
+
|
|
33
|
+
static void osp_free(lcbcrypto_PROVIDER *provider)
|
|
34
|
+
{
|
|
35
|
+
free(provider);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void osp_release_bytes(lcbcrypto_PROVIDER *provider, void *bytes)
|
|
39
|
+
{
|
|
40
|
+
free(bytes);
|
|
41
|
+
(void)provider;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static lcb_error_t osp_load_key(struct lcbcrypto_PROVIDER *provider, lcbcrypto_KEYTYPE type, const char *keyid,
|
|
45
|
+
uint8_t **key, size_t *key_len)
|
|
46
|
+
{
|
|
47
|
+
*key_len = AES256_KEY_SIZE;
|
|
48
|
+
*key = malloc(*key_len);
|
|
49
|
+
memcpy(*key, common_aes256_key, *key_len);
|
|
50
|
+
|
|
51
|
+
(void)type;
|
|
52
|
+
(void)keyid;
|
|
53
|
+
(void)provider;
|
|
54
|
+
return LCB_SUCCESS;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static lcb_error_t osp_generate_iv(struct lcbcrypto_PROVIDER *provider, uint8_t **iv, size_t *iv_len)
|
|
58
|
+
{
|
|
59
|
+
*iv_len = AES256_IV_SIZE;
|
|
60
|
+
*iv = malloc(*iv_len);
|
|
61
|
+
memcpy(*iv, common_aes256_iv, *iv_len);
|
|
62
|
+
|
|
63
|
+
(void)provider;
|
|
64
|
+
return LCB_SUCCESS;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static lcb_error_t osp_sign(struct lcbcrypto_PROVIDER *provider, const lcbcrypto_SIGV *inputs, size_t inputs_num,
|
|
68
|
+
uint8_t **sig, size_t *sig_len)
|
|
69
|
+
{
|
|
70
|
+
const EVP_MD *md;
|
|
71
|
+
uint8_t out[EVP_MAX_MD_SIZE];
|
|
72
|
+
size_t out_len = EVP_MAX_MD_SIZE;
|
|
73
|
+
int rc, key_len = strlen((const char *)common_hmac_sha256_key);
|
|
74
|
+
EVP_MD_CTX *ctx = NULL;
|
|
75
|
+
EVP_PKEY *key = NULL;
|
|
76
|
+
size_t ii;
|
|
77
|
+
|
|
78
|
+
md = EVP_get_digestbyname("SHA256");
|
|
79
|
+
if (md == NULL) {
|
|
80
|
+
return LCB_EINVAL;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, common_hmac_sha256_key, key_len);
|
|
84
|
+
if (key == NULL) {
|
|
85
|
+
return LCB_EINVAL;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
ctx = EVP_MD_CTX_new();
|
|
89
|
+
if (ctx == NULL) {
|
|
90
|
+
EVP_PKEY_free(key);
|
|
91
|
+
return LCB_EINVAL;
|
|
92
|
+
}
|
|
93
|
+
rc = EVP_DigestSignInit(ctx, NULL, md, NULL, key);
|
|
94
|
+
if (rc != 1) {
|
|
95
|
+
EVP_PKEY_free(key);
|
|
96
|
+
return LCB_EINVAL;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (ii = 0; ii < inputs_num; ii++) {
|
|
100
|
+
rc = EVP_DigestSignUpdate(ctx, inputs[ii].data, inputs[ii].len);
|
|
101
|
+
if (rc != 1) {
|
|
102
|
+
EVP_PKEY_free(key);
|
|
103
|
+
EVP_MD_CTX_destroy(ctx);
|
|
104
|
+
return LCB_EINVAL;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
rc = EVP_DigestSignFinal(ctx, out, &out_len);
|
|
108
|
+
if (rc != 1 || out_len == 0) {
|
|
109
|
+
EVP_PKEY_free(key);
|
|
110
|
+
EVP_MD_CTX_destroy(ctx);
|
|
111
|
+
return LCB_EINVAL;
|
|
112
|
+
}
|
|
113
|
+
*sig = malloc(out_len);
|
|
114
|
+
memcpy(*sig, out, out_len);
|
|
115
|
+
*sig_len = out_len;
|
|
116
|
+
|
|
117
|
+
return LCB_SUCCESS;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static lcb_error_t osp_verify_signature(struct lcbcrypto_PROVIDER *provider, const lcbcrypto_SIGV *inputs,
|
|
121
|
+
size_t inputs_num, uint8_t *sig, size_t sig_len)
|
|
122
|
+
{
|
|
123
|
+
const EVP_MD *md;
|
|
124
|
+
uint8_t actual[EVP_MAX_MD_SIZE];
|
|
125
|
+
size_t actual_len = EVP_MAX_MD_SIZE;
|
|
126
|
+
int rc, key_len = strlen((const char *)common_hmac_sha256_key);
|
|
127
|
+
EVP_MD_CTX *ctx = NULL;
|
|
128
|
+
EVP_PKEY *key = NULL;
|
|
129
|
+
size_t ii;
|
|
130
|
+
|
|
131
|
+
md = EVP_get_digestbyname("SHA256");
|
|
132
|
+
if (md == NULL) {
|
|
133
|
+
return LCB_EINVAL;
|
|
134
|
+
}
|
|
135
|
+
key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, common_hmac_sha256_key, key_len);
|
|
136
|
+
if (key == NULL) {
|
|
137
|
+
return LCB_EINVAL;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
ctx = EVP_MD_CTX_new();
|
|
141
|
+
if (ctx == NULL) {
|
|
142
|
+
EVP_PKEY_free(key);
|
|
143
|
+
return LCB_EINVAL;
|
|
144
|
+
}
|
|
145
|
+
rc = EVP_DigestSignInit(ctx, NULL, md, NULL, key);
|
|
146
|
+
if (rc != 1) {
|
|
147
|
+
EVP_PKEY_free(key);
|
|
148
|
+
return LCB_EINVAL;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
for (ii = 0; ii < inputs_num; ii++) {
|
|
152
|
+
rc = EVP_DigestSignUpdate(ctx, inputs[ii].data, inputs[ii].len);
|
|
153
|
+
if (rc != 1) {
|
|
154
|
+
EVP_PKEY_free(key);
|
|
155
|
+
EVP_MD_CTX_destroy(ctx);
|
|
156
|
+
return LCB_EINVAL;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
rc = EVP_DigestSignFinal(ctx, actual, &actual_len);
|
|
160
|
+
if (rc != 1 || actual_len == 0) {
|
|
161
|
+
EVP_PKEY_free(key);
|
|
162
|
+
EVP_MD_CTX_destroy(ctx);
|
|
163
|
+
return LCB_EINVAL;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (memcmp(actual, sig, sig_len < actual_len ? sig_len : actual_len) == 0) {
|
|
167
|
+
return LCB_SUCCESS;
|
|
168
|
+
}
|
|
169
|
+
return LCB_EINVAL;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static lcb_error_t osp_encrypt(struct lcbcrypto_PROVIDER *provider, const uint8_t *input, size_t input_len,
|
|
173
|
+
const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, uint8_t **output,
|
|
174
|
+
size_t *output_len)
|
|
175
|
+
{
|
|
176
|
+
EVP_CIPHER_CTX *ctx;
|
|
177
|
+
const EVP_CIPHER *cipher;
|
|
178
|
+
int rc, len, block_len, out_len;
|
|
179
|
+
uint8_t *out;
|
|
180
|
+
|
|
181
|
+
if (iv_len != 16 || key_len != 32) {
|
|
182
|
+
return LCB_EINVAL;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
ctx = EVP_CIPHER_CTX_new();
|
|
186
|
+
if (!ctx) {
|
|
187
|
+
return LCB_EINVAL;
|
|
188
|
+
}
|
|
189
|
+
cipher = EVP_aes_256_cbc();
|
|
190
|
+
rc = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv);
|
|
191
|
+
if (rc != 1) {
|
|
192
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
193
|
+
return LCB_EINVAL;
|
|
194
|
+
}
|
|
195
|
+
block_len = EVP_CIPHER_block_size(cipher);
|
|
196
|
+
out = calloc(input_len + block_len - 1, sizeof(uint8_t));
|
|
197
|
+
rc = EVP_EncryptUpdate(ctx, out, &len, input, input_len);
|
|
198
|
+
if (rc != 1) {
|
|
199
|
+
free(out);
|
|
200
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
201
|
+
return LCB_EINVAL;
|
|
202
|
+
}
|
|
203
|
+
out_len = len;
|
|
204
|
+
rc = EVP_EncryptFinal_ex(ctx, out + len, &len);
|
|
205
|
+
if (rc != 1) {
|
|
206
|
+
free(out);
|
|
207
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
208
|
+
return LCB_EINVAL;
|
|
209
|
+
}
|
|
210
|
+
out_len += len;
|
|
211
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
212
|
+
*output = out;
|
|
213
|
+
*output_len = out_len;
|
|
214
|
+
return LCB_SUCCESS;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static lcb_error_t osp_decrypt(struct lcbcrypto_PROVIDER *provider, const uint8_t *input, size_t input_len,
|
|
218
|
+
const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, uint8_t **output,
|
|
219
|
+
size_t *output_len)
|
|
220
|
+
{
|
|
221
|
+
EVP_CIPHER_CTX *ctx;
|
|
222
|
+
const EVP_CIPHER *cipher;
|
|
223
|
+
int rc, len, out_len;
|
|
224
|
+
uint8_t *out;
|
|
225
|
+
|
|
226
|
+
if (iv_len != 16 || key_len != 32) {
|
|
227
|
+
return LCB_EINVAL;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
ctx = EVP_CIPHER_CTX_new();
|
|
231
|
+
if (!ctx) {
|
|
232
|
+
return LCB_EINVAL;
|
|
233
|
+
}
|
|
234
|
+
cipher = EVP_aes_256_cbc();
|
|
235
|
+
rc = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv);
|
|
236
|
+
if (rc != 1) {
|
|
237
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
238
|
+
return LCB_EINVAL;
|
|
239
|
+
}
|
|
240
|
+
out = calloc(input_len, sizeof(uint8_t));
|
|
241
|
+
rc = EVP_DecryptUpdate(ctx, out, &len, input, input_len);
|
|
242
|
+
if (rc != 1) {
|
|
243
|
+
free(out);
|
|
244
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
245
|
+
return LCB_EINVAL;
|
|
246
|
+
}
|
|
247
|
+
out_len = len;
|
|
248
|
+
rc = EVP_DecryptFinal_ex(ctx, out + len, &len);
|
|
249
|
+
if (rc != 1) {
|
|
250
|
+
free(out);
|
|
251
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
252
|
+
return LCB_EINVAL;
|
|
253
|
+
}
|
|
254
|
+
out_len += len;
|
|
255
|
+
EVP_CIPHER_CTX_free(ctx);
|
|
256
|
+
*output = out;
|
|
257
|
+
*output_len = out_len;
|
|
258
|
+
return LCB_SUCCESS;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
lcbcrypto_PROVIDER *osp_create()
|
|
262
|
+
{
|
|
263
|
+
lcbcrypto_PROVIDER *provider = calloc(1, sizeof(lcbcrypto_PROVIDER));
|
|
264
|
+
provider->version = 0;
|
|
265
|
+
provider->destructor = osp_free;
|
|
266
|
+
provider->v.v0.release_bytes = osp_release_bytes;
|
|
267
|
+
provider->v.v0.load_key = osp_load_key;
|
|
268
|
+
provider->v.v0.generate_iv = osp_generate_iv;
|
|
269
|
+
provider->v.v0.sign = osp_sign;
|
|
270
|
+
provider->v.v0.verify_signature = osp_verify_signature;
|
|
271
|
+
provider->v.v0.encrypt = osp_encrypt;
|
|
272
|
+
provider->v.v0.decrypt = osp_decrypt;
|
|
273
|
+
return provider;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
void osp_initialize()
|
|
277
|
+
{
|
|
278
|
+
SSL_library_init();
|
|
279
|
+
SSL_load_error_strings();
|
|
280
|
+
EVP_add_cipher(EVP_aes_256_cbc());
|
|
281
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2018 Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef _OPENSSL_SYMMETRIC_PROVIDER_H
|
|
19
|
+
#define _OPENSSL_SYMMETRIC_PROVIDER_H
|
|
20
|
+
|
|
21
|
+
#include <libcouchbase/couchbase.h>
|
|
22
|
+
#include <libcouchbase/crypto.h>
|
|
23
|
+
|
|
24
|
+
#include "common_provider.h"
|
|
25
|
+
|
|
26
|
+
void osp_initialize();
|
|
27
|
+
lcbcrypto_PROVIDER *osp_create();
|
|
28
|
+
|
|
29
|
+
#endif
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ext/libcouchbase/example/tracing/../../contrib/cJSON/cJSON.c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ext/libcouchbase/example/tracing/../../contrib/cJSON/cJSON.h
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2018 Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @file
|
|
20
|
+
*
|
|
21
|
+
* This is a minimal example file showing how to connect to a cluster and
|
|
22
|
+
* set and retrieve a single item. This is copy of minimal.c, but with
|
|
23
|
+
* tracing enabled.
|
|
24
|
+
*
|
|
25
|
+
* docker run -d -p 9411:9411 openzipkin/zipkin
|
|
26
|
+
* make
|
|
27
|
+
* ./tracing couchbase://localhost password Administrator
|
|
28
|
+
*
|
|
29
|
+
* open browser at http://localhost:9411
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
#include <stdio.h>
|
|
33
|
+
#include <libcouchbase/couchbase.h>
|
|
34
|
+
#include <libcouchbase/api3.h>
|
|
35
|
+
#include <stdlib.h>
|
|
36
|
+
#include <unistd.h>
|
|
37
|
+
#include <string.h> /* strlen */
|
|
38
|
+
#ifdef _WIN32
|
|
39
|
+
#define PRIx64 "I64x"
|
|
40
|
+
#define PRId64 "I64d"
|
|
41
|
+
#else
|
|
42
|
+
#include <inttypes.h>
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#include <netdb.h>
|
|
46
|
+
#include <sys/types.h>
|
|
47
|
+
#include <netinet/in.h>
|
|
48
|
+
#include <sys/socket.h>
|
|
49
|
+
#include <arpa/inet.h>
|
|
50
|
+
|
|
51
|
+
#include "cJSON.h"
|
|
52
|
+
|
|
53
|
+
#define COMPONENT_NAME "demo"
|
|
54
|
+
|
|
55
|
+
struct zipkin_payload;
|
|
56
|
+
typedef struct zipkin_payload {
|
|
57
|
+
char *data;
|
|
58
|
+
struct zipkin_payload *next;
|
|
59
|
+
} zipkin_payload;
|
|
60
|
+
|
|
61
|
+
typedef struct zipkin_state {
|
|
62
|
+
char *json_api_host;
|
|
63
|
+
char *json_api_port;
|
|
64
|
+
/* [0, 100], where 0 is "never", 100 is "always" */
|
|
65
|
+
int sample_rate;
|
|
66
|
+
zipkin_payload *root;
|
|
67
|
+
zipkin_payload *last;
|
|
68
|
+
size_t content_length;
|
|
69
|
+
} zipkin_state;
|
|
70
|
+
|
|
71
|
+
void zipkin_destructor(lcbtrace_TRACER *tracer)
|
|
72
|
+
{
|
|
73
|
+
if (tracer) {
|
|
74
|
+
if (tracer->cookie) {
|
|
75
|
+
free(tracer->cookie);
|
|
76
|
+
tracer->cookie = NULL;
|
|
77
|
+
}
|
|
78
|
+
free(tracer);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void zipkin_report(lcbtrace_TRACER *tracer, lcbtrace_SPAN *span)
|
|
83
|
+
{
|
|
84
|
+
zipkin_state *state = NULL;
|
|
85
|
+
|
|
86
|
+
if (tracer == NULL) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
state = tracer->cookie;
|
|
90
|
+
if (state == NULL) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (rand() % 100 > state->sample_rate) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
{
|
|
98
|
+
#define BUFSZ 1000
|
|
99
|
+
size_t nbuf = BUFSZ;
|
|
100
|
+
char *buf;
|
|
101
|
+
lcbtrace_SPAN *parent;
|
|
102
|
+
uint64_t start;
|
|
103
|
+
zipkin_payload *payload = calloc(1, sizeof(zipkin_payload));
|
|
104
|
+
cJSON *json = cJSON_CreateObject();
|
|
105
|
+
|
|
106
|
+
buf = calloc(nbuf, sizeof(char));
|
|
107
|
+
cJSON_AddItemToObject(json, "name", cJSON_CreateString(lcbtrace_span_get_operation(span)));
|
|
108
|
+
snprintf(buf, nbuf, "%" PRIx64, lcbtrace_span_get_span_id(span));
|
|
109
|
+
cJSON_AddItemToObject(json, "id", cJSON_CreateString(buf));
|
|
110
|
+
snprintf(buf, nbuf, "%" PRIx64, lcbtrace_span_get_trace_id(span));
|
|
111
|
+
cJSON_AddItemToObject(json, "traceId", cJSON_CreateString(buf));
|
|
112
|
+
parent = lcbtrace_span_get_parent(span);
|
|
113
|
+
if (parent) {
|
|
114
|
+
snprintf(buf, nbuf, "%" PRIx64, lcbtrace_span_get_trace_id(parent));
|
|
115
|
+
cJSON_AddItemToObject(json, "parentId", cJSON_CreateString(buf));
|
|
116
|
+
}
|
|
117
|
+
start = lcbtrace_span_get_start_ts(span);
|
|
118
|
+
cJSON_AddItemToObject(json, "timestamp", cJSON_CreateNumber(start));
|
|
119
|
+
cJSON_AddItemToObject(json, "duration", cJSON_CreateNumber(lcbtrace_span_get_finish_ts(span) - start));
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
cJSON *endpoint = cJSON_CreateObject();
|
|
123
|
+
|
|
124
|
+
nbuf = BUFSZ;
|
|
125
|
+
if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_DB_TYPE, &buf, &nbuf) == LCB_SUCCESS) {
|
|
126
|
+
buf[nbuf] = '\0';
|
|
127
|
+
cJSON_AddItemToObject(endpoint, "serviceName", cJSON_CreateString(buf));
|
|
128
|
+
}
|
|
129
|
+
cJSON_AddItemToObject(json, "localEndpoint", endpoint);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
cJSON *tags = cJSON_CreateObject();
|
|
134
|
+
uint64_t latency, operation_id;
|
|
135
|
+
if (lcbtrace_span_get_tag_uint64(span, LCBTRACE_TAG_PEER_LATENCY, &latency) == LCB_SUCCESS) {
|
|
136
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_PEER_LATENCY, cJSON_CreateNumber(latency));
|
|
137
|
+
}
|
|
138
|
+
if (lcbtrace_span_get_tag_uint64(span, LCBTRACE_TAG_OPERATION_ID, &operation_id) == LCB_SUCCESS) {
|
|
139
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_OPERATION_ID, cJSON_CreateNumber(operation_id));
|
|
140
|
+
}
|
|
141
|
+
nbuf = BUFSZ;
|
|
142
|
+
if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_COMPONENT, &buf, &nbuf) == LCB_SUCCESS) {
|
|
143
|
+
buf[nbuf] = '\0';
|
|
144
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_COMPONENT, cJSON_CreateString(buf));
|
|
145
|
+
}
|
|
146
|
+
nbuf = BUFSZ;
|
|
147
|
+
if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_PEER_ADDRESS, &buf, &nbuf) == LCB_SUCCESS) {
|
|
148
|
+
buf[nbuf] = '\0';
|
|
149
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_PEER_ADDRESS, cJSON_CreateString(buf));
|
|
150
|
+
}
|
|
151
|
+
nbuf = BUFSZ;
|
|
152
|
+
if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_LOCAL_ADDRESS, &buf, &nbuf) == LCB_SUCCESS) {
|
|
153
|
+
buf[nbuf] = '\0';
|
|
154
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_LOCAL_ADDRESS, cJSON_CreateString(buf));
|
|
155
|
+
}
|
|
156
|
+
nbuf = BUFSZ;
|
|
157
|
+
if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_DB_INSTANCE, &buf, &nbuf) == LCB_SUCCESS) {
|
|
158
|
+
buf[nbuf] = '\0';
|
|
159
|
+
cJSON_AddItemToObject(tags, LCBTRACE_TAG_DB_INSTANCE, cJSON_CreateString(buf));
|
|
160
|
+
}
|
|
161
|
+
if (cJSON_GetArraySize(tags) > 0) {
|
|
162
|
+
cJSON_AddItemToObject(json, "tags", tags);
|
|
163
|
+
} else {
|
|
164
|
+
cJSON_Delete(tags);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
free(buf);
|
|
168
|
+
|
|
169
|
+
payload->data = cJSON_PrintUnformatted(json);
|
|
170
|
+
cJSON_Delete(json);
|
|
171
|
+
if (state->last) {
|
|
172
|
+
state->last->next = payload;
|
|
173
|
+
}
|
|
174
|
+
state->last = payload;
|
|
175
|
+
state->content_length += strlen(payload->data) + 1; /* for comma/closing bracket */
|
|
176
|
+
if (state->root == NULL) {
|
|
177
|
+
state->root = payload;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void loop_send(int sock, char *bytes, ssize_t nbytes)
|
|
183
|
+
{
|
|
184
|
+
do {
|
|
185
|
+
ssize_t rv = send(sock, bytes, nbytes, 0);
|
|
186
|
+
if (rv < 0) {
|
|
187
|
+
perror("failed to send data to zipkin: ");
|
|
188
|
+
exit(EXIT_FAILURE);
|
|
189
|
+
} else if (rv < nbytes) {
|
|
190
|
+
nbytes -= rv;
|
|
191
|
+
bytes += rv;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
} while (1);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
void zipkin_flush(lcbtrace_TRACER *tracer)
|
|
199
|
+
{
|
|
200
|
+
zipkin_state *state = NULL;
|
|
201
|
+
int sock, rv;
|
|
202
|
+
|
|
203
|
+
if (tracer == NULL) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
state = tracer->cookie;
|
|
207
|
+
if (state == NULL) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (state->root == NULL || state->content_length == 0) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
{
|
|
214
|
+
struct addrinfo hints, *addr, *a;
|
|
215
|
+
|
|
216
|
+
memset(&hints, 0, sizeof(hints));
|
|
217
|
+
hints.ai_family = AF_UNSPEC;
|
|
218
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
219
|
+
rv = getaddrinfo(state->json_api_host, state->json_api_port, &hints, &addr);
|
|
220
|
+
if (rv != 0) {
|
|
221
|
+
fprintf(stderr, "failed to resolve zipkin address getaddrinfo: %s\n", gai_strerror(rv));
|
|
222
|
+
exit(EXIT_FAILURE);
|
|
223
|
+
}
|
|
224
|
+
for (a = addr; a != NULL; a = a->ai_next) {
|
|
225
|
+
sock = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
|
|
226
|
+
if (sock == -1) {
|
|
227
|
+
perror("failed to create socket for zipkin: ");
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
rv = connect(sock, a->ai_addr, a->ai_addrlen);
|
|
231
|
+
if (rv == -1) {
|
|
232
|
+
perror("failed to connect socket for zipkin: ");
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
if (a == NULL) {
|
|
238
|
+
fprintf(stderr, "unable to connect to zipkin. terminating\n");
|
|
239
|
+
exit(EXIT_FAILURE);
|
|
240
|
+
}
|
|
241
|
+
freeaddrinfo(addr);
|
|
242
|
+
}
|
|
243
|
+
{
|
|
244
|
+
char preamble[1000] = "";
|
|
245
|
+
size_t size;
|
|
246
|
+
|
|
247
|
+
snprintf(preamble, sizeof(preamble),
|
|
248
|
+
"POST /api/v2/spans HTTP/1.1\r\n"
|
|
249
|
+
"Content-Type: application/json\r\n"
|
|
250
|
+
"Accept: */*\r\n"
|
|
251
|
+
"Connection: close\r\n"
|
|
252
|
+
"Host: %s:%s\r\n"
|
|
253
|
+
"Content-Length: %ld\r\n\r\n",
|
|
254
|
+
state->json_api_host, state->json_api_port, (long)state->content_length + 1 /* for open bracket */);
|
|
255
|
+
size = strlen(preamble);
|
|
256
|
+
|
|
257
|
+
rv = send(sock, preamble, size, 0);
|
|
258
|
+
if (rv == -1) {
|
|
259
|
+
perror("failed to send HTTP headers to zipkin: ");
|
|
260
|
+
exit(EXIT_FAILURE);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
{
|
|
264
|
+
zipkin_payload *ptr = state->root;
|
|
265
|
+
loop_send(sock, "[", 1);
|
|
266
|
+
while (ptr) {
|
|
267
|
+
zipkin_payload *tmp = ptr;
|
|
268
|
+
loop_send(sock, ptr->data, strlen(ptr->data));
|
|
269
|
+
ptr = ptr->next;
|
|
270
|
+
if (ptr) {
|
|
271
|
+
loop_send(sock, ",", 1);
|
|
272
|
+
}
|
|
273
|
+
free(tmp->data);
|
|
274
|
+
free(tmp);
|
|
275
|
+
}
|
|
276
|
+
loop_send(sock, "]", 1);
|
|
277
|
+
}
|
|
278
|
+
close(sock);
|
|
279
|
+
state->root = state->last = NULL;
|
|
280
|
+
state->content_length = 0;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
lcbtrace_TRACER *zipkin_new()
|
|
284
|
+
{
|
|
285
|
+
lcbtrace_TRACER *tracer = calloc(1, sizeof(lcbtrace_TRACER));
|
|
286
|
+
zipkin_state *zipkin = calloc(1, sizeof(zipkin_state));
|
|
287
|
+
tracer->destructor = zipkin_destructor;
|
|
288
|
+
tracer->flags = 0;
|
|
289
|
+
tracer->version = 0;
|
|
290
|
+
tracer->v.v0.report = zipkin_report;
|
|
291
|
+
zipkin->json_api_host = "localhost";
|
|
292
|
+
zipkin->json_api_port = "9411";
|
|
293
|
+
zipkin->sample_rate = 100;
|
|
294
|
+
zipkin->root = NULL;
|
|
295
|
+
zipkin->last = NULL;
|
|
296
|
+
zipkin->content_length = 0;
|
|
297
|
+
tracer->cookie = zipkin;
|
|
298
|
+
return tracer;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static void die(lcb_t instance, const char *msg, lcb_error_t err)
|
|
302
|
+
{
|
|
303
|
+
fprintf(stderr, "%s. Received code 0x%X (%s)\n", msg, err, lcb_strerror(instance, err));
|
|
304
|
+
exit(EXIT_FAILURE);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
static void op_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
|
|
308
|
+
{
|
|
309
|
+
fprintf(stderr, "=== %s ===\n", lcb_strcbtype(cbtype));
|
|
310
|
+
if (rb->rc == LCB_SUCCESS) {
|
|
311
|
+
fprintf(stderr, "KEY: %.*s\n", (int)rb->nkey, rb->key);
|
|
312
|
+
fprintf(stderr, "CAS: 0x%" PRIx64 "\n", rb->cas);
|
|
313
|
+
if (cbtype == LCB_CALLBACK_GET) {
|
|
314
|
+
const lcb_RESPGET *rg = (const lcb_RESPGET *)rb;
|
|
315
|
+
fprintf(stderr, "VALUE: %.*s\n", (int)rg->nvalue, rg->value);
|
|
316
|
+
fprintf(stderr, "FLAGS: 0x%x\n", rg->itmflags);
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
die(instance, lcb_strcbtype(cbtype), rb->rc);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
int main(int argc, char *argv[])
|
|
324
|
+
{
|
|
325
|
+
lcb_error_t err;
|
|
326
|
+
lcb_t instance;
|
|
327
|
+
struct lcb_create_st create_options = {0};
|
|
328
|
+
lcb_CMDSTORE scmd = {0};
|
|
329
|
+
lcb_CMDGET gcmd = {0};
|
|
330
|
+
lcbtrace_SPAN *span = NULL;
|
|
331
|
+
lcbtrace_TRACER *tracer = NULL;
|
|
332
|
+
|
|
333
|
+
create_options.version = 3;
|
|
334
|
+
|
|
335
|
+
if (argc < 2) {
|
|
336
|
+
fprintf(stderr, "Usage: %s couchbase://host/bucket [ password [ username ] ]\n", argv[0]);
|
|
337
|
+
exit(EXIT_FAILURE);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
create_options.v.v3.connstr = argv[1];
|
|
341
|
+
if (argc > 2) {
|
|
342
|
+
create_options.v.v3.passwd = argv[2];
|
|
343
|
+
}
|
|
344
|
+
if (argc > 3) {
|
|
345
|
+
create_options.v.v3.username = argv[3];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
srand(time(NULL));
|
|
349
|
+
|
|
350
|
+
err = lcb_create(&instance, &create_options);
|
|
351
|
+
if (err != LCB_SUCCESS) {
|
|
352
|
+
die(NULL, "Couldn't create couchbase handle", err);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
err = lcb_connect(instance);
|
|
356
|
+
if (err != LCB_SUCCESS) {
|
|
357
|
+
die(instance, "Couldn't schedule connection", err);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
lcb_wait(instance);
|
|
361
|
+
|
|
362
|
+
err = lcb_get_bootstrap_status(instance);
|
|
363
|
+
if (err != LCB_SUCCESS) {
|
|
364
|
+
die(instance, "Couldn't bootstrap from cluster", err);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* Assign the handlers to be called for the operation types */
|
|
368
|
+
lcb_install_callback3(instance, LCB_CALLBACK_GET, op_callback);
|
|
369
|
+
lcb_install_callback3(instance, LCB_CALLBACK_STORE, op_callback);
|
|
370
|
+
|
|
371
|
+
tracer = zipkin_new();
|
|
372
|
+
|
|
373
|
+
lcb_set_tracer(instance, tracer);
|
|
374
|
+
|
|
375
|
+
span = lcbtrace_span_start(tracer, "transaction", 0, NULL);
|
|
376
|
+
lcbtrace_span_add_tag_str(span, LCBTRACE_TAG_COMPONENT, COMPONENT_NAME);
|
|
377
|
+
|
|
378
|
+
{
|
|
379
|
+
int encoding_time_us = rand() % 1000;
|
|
380
|
+
lcbtrace_SPAN *encoding;
|
|
381
|
+
lcbtrace_REF ref;
|
|
382
|
+
|
|
383
|
+
ref.type = LCBTRACE_REF_CHILD_OF;
|
|
384
|
+
ref.span = span;
|
|
385
|
+
|
|
386
|
+
encoding = lcbtrace_span_start(tracer, LCBTRACE_OP_REQUEST_ENCODING, 0, &ref);
|
|
387
|
+
lcbtrace_span_add_tag_str(encoding, LCBTRACE_TAG_COMPONENT, COMPONENT_NAME);
|
|
388
|
+
usleep(encoding_time_us);
|
|
389
|
+
lcbtrace_span_finish(encoding, LCBTRACE_NOW);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
LCB_CMD_SET_TRACESPAN(&scmd, span);
|
|
393
|
+
LCB_CMD_SET_KEY(&scmd, "key", strlen("key"));
|
|
394
|
+
LCB_CMD_SET_VALUE(&scmd, "value", strlen("value"));
|
|
395
|
+
scmd.operation = LCB_SET;
|
|
396
|
+
err = lcb_store3(instance, NULL, &scmd);
|
|
397
|
+
if (err != LCB_SUCCESS) {
|
|
398
|
+
die(instance, "Couldn't schedule storage operation", err);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* The store_callback is invoked from lcb_wait() */
|
|
402
|
+
fprintf(stderr, "Will wait for storage operation to complete..\n");
|
|
403
|
+
lcb_wait(instance);
|
|
404
|
+
|
|
405
|
+
/* Now fetch the item back */
|
|
406
|
+
LCB_CMD_SET_TRACESPAN(&gcmd, span);
|
|
407
|
+
LCB_CMD_SET_KEY(&gcmd, "key", strlen("key"));
|
|
408
|
+
err = lcb_get3(instance, NULL, &gcmd);
|
|
409
|
+
if (err != LCB_SUCCESS) {
|
|
410
|
+
die(instance, "Couldn't schedule retrieval operation", err);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* Likewise, the get_callback is invoked from here */
|
|
414
|
+
fprintf(stderr, "Will wait to retrieve item..\n");
|
|
415
|
+
lcb_wait(instance);
|
|
416
|
+
|
|
417
|
+
{
|
|
418
|
+
int decoding_time_us = rand() % 1000;
|
|
419
|
+
lcbtrace_SPAN *decoding;
|
|
420
|
+
lcbtrace_REF ref;
|
|
421
|
+
|
|
422
|
+
ref.type = LCBTRACE_REF_CHILD_OF;
|
|
423
|
+
ref.span = span;
|
|
424
|
+
|
|
425
|
+
decoding = lcbtrace_span_start(tracer, LCBTRACE_OP_RESPONSE_DECODING, 0, &ref);
|
|
426
|
+
lcbtrace_span_add_tag_str(decoding, LCBTRACE_TAG_COMPONENT, COMPONENT_NAME);
|
|
427
|
+
usleep(decoding_time_us);
|
|
428
|
+
lcbtrace_span_finish(decoding, LCBTRACE_NOW);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
lcbtrace_span_finish(span, LCBTRACE_NOW);
|
|
432
|
+
|
|
433
|
+
zipkin_flush(tracer);
|
|
434
|
+
|
|
435
|
+
/* Now that we're all done, close down the connection handle */
|
|
436
|
+
lcb_destroy(instance);
|
|
437
|
+
|
|
438
|
+
return 0;
|
|
439
|
+
}
|