libcouchbase 1.2.8 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/README.md +16 -8
  4. data/ext/libcouchbase/CMakeLists.txt +34 -32
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
  7. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  10. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
  11. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  12. data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
  13. data/ext/libcouchbase/cmake/configure +8 -26
  14. data/ext/libcouchbase/cmake/defs.mk.in +2 -2
  15. data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
  16. data/ext/libcouchbase/cmake/source_files.cmake +11 -2
  17. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
  18. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
  19. data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
  20. data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
  21. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
  22. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
  23. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
  24. data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
  25. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
  26. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
  27. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
  28. data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
  29. data/ext/libcouchbase/example/crypto/.gitignore +2 -0
  30. data/ext/libcouchbase/example/crypto/Makefile +13 -0
  31. data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
  32. data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
  33. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
  34. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
  35. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
  36. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
  37. data/ext/libcouchbase/example/tracing/.gitignore +2 -0
  38. data/ext/libcouchbase/example/tracing/Makefile +8 -0
  39. data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
  40. data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
  41. data/ext/libcouchbase/example/tracing/tracing.c +439 -0
  42. data/ext/libcouchbase/example/tracing/views.c +444 -0
  43. data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
  44. data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
  45. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
  46. data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
  47. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
  48. data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
  49. data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
  50. data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
  51. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
  52. data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
  53. data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
  54. data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
  55. data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
  56. data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
  57. data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
  58. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
  59. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
  60. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
  61. data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
  62. data/ext/libcouchbase/src/auth-priv.h +36 -4
  63. data/ext/libcouchbase/src/auth.cc +66 -27
  64. data/ext/libcouchbase/src/bootstrap.cc +1 -1
  65. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
  66. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
  67. data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
  68. data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
  69. data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
  70. data/ext/libcouchbase/src/cbft.cc +48 -0
  71. data/ext/libcouchbase/src/cntl.cc +138 -2
  72. data/ext/libcouchbase/src/config_static.h +17 -0
  73. data/ext/libcouchbase/src/connspec.cc +54 -6
  74. data/ext/libcouchbase/src/connspec.h +9 -1
  75. data/ext/libcouchbase/src/crypto.cc +386 -0
  76. data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
  77. data/ext/libcouchbase/src/dump.cc +4 -0
  78. data/ext/libcouchbase/src/getconfig.cc +1 -2
  79. data/ext/libcouchbase/src/handler.cc +65 -27
  80. data/ext/libcouchbase/src/hostlist.cc +35 -7
  81. data/ext/libcouchbase/src/hostlist.h +7 -0
  82. data/ext/libcouchbase/src/http/http-priv.h +2 -0
  83. data/ext/libcouchbase/src/http/http.cc +77 -37
  84. data/ext/libcouchbase/src/http/http_io.cc +19 -2
  85. data/ext/libcouchbase/src/instance.cc +90 -17
  86. data/ext/libcouchbase/src/internal.h +5 -0
  87. data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
  88. data/ext/libcouchbase/src/lcbio/connect.h +27 -0
  89. data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
  90. data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
  91. data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
  92. data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
  93. data/ext/libcouchbase/src/lcbio/manager.h +2 -0
  94. data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
  95. data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
  96. data/ext/libcouchbase/src/logging.c +1 -1
  97. data/ext/libcouchbase/src/logging.h +2 -0
  98. data/ext/libcouchbase/src/mc/compress.cc +164 -0
  99. data/ext/libcouchbase/src/mc/compress.h +7 -12
  100. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
  101. data/ext/libcouchbase/src/mc/mcreq.c +11 -1
  102. data/ext/libcouchbase/src/mc/mcreq.h +35 -4
  103. data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
  104. data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
  105. data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
  106. data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
  107. data/ext/libcouchbase/src/mctx-helper.h +11 -0
  108. data/ext/libcouchbase/src/metrics.cc +132 -0
  109. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  110. data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
  111. data/ext/libcouchbase/src/newconfig.cc +9 -2
  112. data/ext/libcouchbase/src/operations/counter.cc +2 -1
  113. data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
  114. data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
  115. data/ext/libcouchbase/src/operations/durability.cc +24 -2
  116. data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
  117. data/ext/libcouchbase/src/operations/get.cc +4 -2
  118. data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
  119. data/ext/libcouchbase/src/operations/observe.cc +113 -62
  120. data/ext/libcouchbase/src/operations/ping.cc +246 -67
  121. data/ext/libcouchbase/src/operations/remove.cc +2 -1
  122. data/ext/libcouchbase/src/operations/store.cc +17 -14
  123. data/ext/libcouchbase/src/operations/touch.cc +3 -0
  124. data/ext/libcouchbase/src/packetutils.h +68 -4
  125. data/ext/libcouchbase/src/probes.d +132 -161
  126. data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
  127. data/ext/libcouchbase/src/retryq.cc +6 -2
  128. data/ext/libcouchbase/src/rnd.cc +68 -0
  129. data/ext/libcouchbase/src/rnd.h +39 -0
  130. data/ext/libcouchbase/src/settings.c +27 -0
  131. data/ext/libcouchbase/src/settings.h +67 -3
  132. data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
  133. data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
  134. data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
  135. data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
  136. data/ext/libcouchbase/src/trace.h +68 -61
  137. data/ext/libcouchbase/src/tracing/span.cc +289 -0
  138. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
  139. data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
  140. data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
  141. data/ext/libcouchbase/src/utilities.c +5 -0
  142. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
  143. data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
  144. data/ext/libcouchbase/src/views/docreq.cc +26 -1
  145. data/ext/libcouchbase/src/views/docreq.h +17 -0
  146. data/ext/libcouchbase/src/views/viewreq.cc +64 -1
  147. data/ext/libcouchbase/src/views/viewreq.h +21 -0
  148. data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
  149. data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
  150. data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
  151. data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
  152. data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
  153. data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
  154. data/ext/libcouchbase/tests/check-all.cc +6 -2
  155. data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
  156. data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
  157. data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
  158. data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
  159. data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
  160. data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
  161. data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
  162. data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
  163. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  164. data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
  165. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  166. data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
  167. data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
  168. data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
  169. data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
  170. data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
  171. data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
  172. data/ext/libcouchbase/tools/cbc.cc +113 -8
  173. data/ext/libcouchbase/tools/common/histogram.cc +1 -0
  174. data/ext/libcouchbase/tools/common/options.cc +28 -1
  175. data/ext/libcouchbase/tools/common/options.h +5 -0
  176. data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
  177. data/ext/libcouchbase/tools/docgen/loc.h +5 -4
  178. data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
  179. data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
  180. data/lib/libcouchbase/n1ql.rb +6 -1
  181. data/lib/libcouchbase/version.rb +1 -1
  182. data/spec/connection_spec.rb +6 -6
  183. metadata +38 -5
  184. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
  185. data/ext/libcouchbase/src/mc/compress.c +0 -90
  186. 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,2 @@
1
+ tracing
2
+ views
@@ -0,0 +1,8 @@
1
+ LDFLAGS=-lcouchbase -lm
2
+ CFLAGS=-g
3
+
4
+ all: tracing views
5
+
6
+ tracing: tracing.c cJSON.c
7
+
8
+ views: views.c cJSON.c
@@ -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
+ }