libcouchbase 0.3.3 → 1.0.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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -79,6 +79,7 @@ static lcb_uint32_t *get_timeout_field(lcb_t instance, int cmd)
79
79
  case LCB_CNTL_HTCONFIG_IDLE_TIMEOUT: return &settings->bc_http_stream_time;
80
80
  case LCB_CNTL_RETRY_INTERVAL: return &settings->retry_interval;
81
81
  case LCB_CNTL_RETRY_NMV_INTERVAL: return &settings->retry_nmv_interval;
82
+ case LCB_CNTL_CONFIG_POLL_INTERVAL: return &settings->config_poll_interval;
82
83
  default: return NULL;
83
84
  }
84
85
  }
@@ -145,7 +146,7 @@ HANDLER(retry_backoff_handler) {
145
146
  RETURN_GET_SET(float, LCBT_SETTING(instance, retry_backoff))
146
147
  }
147
148
  HANDLER(http_poolsz_handler) {
148
- RETURN_GET_SET(lcb_SIZE, instance->http_sockpool->maxidle)
149
+ RETURN_GET_SET(lcb_SIZE, instance->http_sockpool->get_options().maxidle)
149
150
  }
150
151
  HANDLER(http_refresh_config_handler) {
151
152
  RETURN_GET_SET(int, LCBT_SETTING(instance, refresh_on_hterr))
@@ -174,6 +175,9 @@ HANDLER(nmv_imm_retry_handler) {
174
175
  HANDLER(tcp_nodelay_handler) {
175
176
  RETURN_GET_SET(int, LCBT_SETTING(instance, tcp_nodelay));
176
177
  }
178
+ HANDLER(tcp_keepalive_handler) {
179
+ RETURN_GET_SET(int, LCBT_SETTING(instance, tcp_keepalive));
180
+ }
177
181
  HANDLER(readj_ts_wait_handler) {
178
182
  RETURN_GET_SET(int, LCBT_SETTING(instance, readj_ts_wait));
179
183
  }
@@ -183,6 +187,25 @@ HANDLER(kv_hg_handler) {
183
187
  HANDLER(read_chunk_size_handler) {
184
188
  RETURN_GET_SET(lcb_U32, LCBT_SETTING(instance, read_chunk_size));
185
189
  }
190
+ HANDLER(enable_errmap_handler) {
191
+ RETURN_GET_SET(int, LCBT_SETTING(instance, use_errmap));
192
+ }
193
+ HANDLER(select_bucket_handler) {
194
+ RETURN_GET_SET(int, LCBT_SETTING(instance, select_bucket));
195
+ }
196
+ HANDLER(send_hello_handler) {
197
+ RETURN_GET_SET(int, LCBT_SETTING(instance, send_hello));
198
+ }
199
+ HANDLER(config_poll_interval_handler) {
200
+ lcb_error_t rv = timeout_common(mode, instance, cmd, arg);
201
+ if (rv == LCB_SUCCESS &&
202
+ (mode == LCB_CNTL_SET || CNTL__MODE_SETSTRING) &&
203
+ // Note: This might be NULL during creation!
204
+ instance->bs_state) {
205
+ instance->bs_state->check_bgpoll();
206
+ }
207
+ return rv;
208
+ }
186
209
 
187
210
  HANDLER(get_kvb) {
188
211
  lcb_cntl_vbinfo_st *vbi = reinterpret_cast<lcb_cntl_vbinfo_st*>(arg);
@@ -198,7 +221,7 @@ HANDLER(get_kvb) {
198
221
 
199
222
 
200
223
  HANDLER(conninfo) {
201
- lcbio_SOCKET *sock;
224
+ const lcbio_SOCKET *sock;
202
225
  lcb_cntl_server_st *si = reinterpret_cast<lcb_cntl_server_st*>(arg);
203
226
  const lcb_host_t *host;
204
227
 
@@ -212,7 +235,7 @@ HANDLER(conninfo) {
212
235
  if (ix < 0 || ix > (int)LCBT_NSERVERS(instance)) {
213
236
  return LCB_ECTL_BADARG;
214
237
  }
215
- server = LCBT_GET_SERVER(instance, ix);
238
+ server = instance->get_server(ix);
216
239
  if (!server) {
217
240
  return LCB_NETWORK_ERROR;
218
241
  }
@@ -224,7 +247,7 @@ HANDLER(conninfo) {
224
247
  }
225
248
  }
226
249
  } else if (cmd == LCB_CNTL_CONFIGNODE_INFO) {
227
- sock = lcb_confmon_get_rest_connection(instance->confmon);
250
+ sock = lcb::clconfig::http_get_conn(instance->confmon);
228
251
  } else {
229
252
  return LCB_ECTL_BADARG;
230
253
  }
@@ -246,7 +269,8 @@ HANDLER(conninfo) {
246
269
 
247
270
  HANDLER(config_cache_loaded_handler) {
248
271
  if (mode != LCB_CNTL_GET) { return LCB_ECTL_UNSUPPMODE; }
249
- *(int *)arg = instance->cur_configinfo && instance->cur_configinfo->origin == LCB_CLCONFIG_FILE;
272
+ *(int *)arg = instance->cur_configinfo &&
273
+ instance->cur_configinfo->get_origin() == lcb::clconfig::CLCONFIG_FILE;
250
274
  (void)cmd; return LCB_SUCCESS;
251
275
  }
252
276
 
@@ -282,9 +306,9 @@ HANDLER(config_transport) {
282
306
  if (mode == LCB_CNTL_SET) { return LCB_ECTL_UNSUPPMODE; }
283
307
  if (!instance->cur_configinfo) { return LCB_CLIENT_ETMPFAIL; }
284
308
 
285
- switch (instance->cur_configinfo->origin) {
286
- case LCB_CLCONFIG_HTTP: *val = LCB_CONFIG_TRANSPORT_HTTP; break;
287
- case LCB_CLCONFIG_CCCP: *val = LCB_CONFIG_TRANSPORT_CCCP; break;
309
+ switch (instance->cur_configinfo->get_origin()) {
310
+ case lcb::clconfig::CLCONFIG_HTTP: *val = LCB_CONFIG_TRANSPORT_HTTP; break;
311
+ case lcb::clconfig::CLCONFIG_CCCP: *val = LCB_CONFIG_TRANSPORT_CCCP; break;
288
312
  default: return LCB_CLIENT_ETMPFAIL;
289
313
  }
290
314
  (void)cmd; return LCB_SUCCESS;
@@ -292,7 +316,7 @@ HANDLER(config_transport) {
292
316
 
293
317
  HANDLER(config_nodes) {
294
318
  const char *node_strs = reinterpret_cast<const char*>(arg);
295
- clconfig_provider *target;
319
+ lcb::clconfig::Provider *target;
296
320
  lcb::Hostlist hostlist;
297
321
  lcb_error_t err;
298
322
 
@@ -309,13 +333,13 @@ HANDLER(config_nodes) {
309
333
  }
310
334
 
311
335
  if (cmd == LCB_CNTL_CONFIG_HTTP_NODES) {
312
- target = lcb_confmon_get_provider(instance->confmon, LCB_CLCONFIG_HTTP);
313
- lcb_clconfig_http_set_nodes(target, &hostlist);
336
+ target = instance->confmon->get_provider(lcb::clconfig::CLCONFIG_HTTP);
314
337
  } else {
315
- target = lcb_confmon_get_provider(instance->confmon, LCB_CLCONFIG_CCCP);
316
- lcb_clconfig_cccp_set_nodes(target, &hostlist);
338
+ target = instance->confmon->get_provider(lcb::clconfig::CLCONFIG_CCCP);
317
339
  }
318
340
 
341
+ target->configure_nodes(hostlist);
342
+
319
343
  return LCB_SUCCESS;
320
344
  }
321
345
 
@@ -327,22 +351,22 @@ HANDLER(init_providers) {
327
351
  }
328
352
 
329
353
  HANDLER(config_cache_handler) {
330
- clconfig_provider *provider;
354
+ using namespace lcb::clconfig;
355
+ Provider *provider;
331
356
 
332
- provider = lcb_confmon_get_provider(instance->confmon, LCB_CLCONFIG_FILE);
357
+ provider = instance->confmon->get_provider(lcb::clconfig::CLCONFIG_FILE);
333
358
  if (mode == LCB_CNTL_SET) {
334
- int rv;
335
- rv = lcb_clconfig_file_set_filename(provider,
359
+ bool rv = file_set_filename(provider,
336
360
  reinterpret_cast<const char*>(arg),
337
361
  cmd == LCB_CNTL_CONFIGCACHE_RO);
338
362
 
339
- if (rv == 0) {
363
+ if (rv) {
340
364
  instance->settings->bc_http_stream_time = LCB_MS2US(10000);
341
365
  return LCB_SUCCESS;
342
366
  }
343
367
  return LCB_ERROR;
344
368
  } else {
345
- *(const char **)arg = lcb_clconfig_file_get_filename(provider);
369
+ *(const char **)arg = file_get_filename(provider);
346
370
  return LCB_SUCCESS;
347
371
  }
348
372
  }
@@ -496,7 +520,7 @@ HANDLER(bucket_auth_handler) {
496
520
  if (mode == LCB_CNTL_SET) {
497
521
  /* Parse the bucket string... */
498
522
  cred = (const lcb_BUCKETCRED *)arg;
499
- lcbauth_add_pass(instance->settings->auth, (*cred)[0], (*cred)[1], LCBAUTH_F_BUCKET);
523
+ return lcbauth_add_pass(instance->settings->auth, (*cred)[0], (*cred)[1], LCBAUTH_F_BUCKET);
500
524
  (void)cmd; (void)arg;
501
525
  } else if (mode == CNTL__MODE_SETSTRING) {
502
526
  const char *ss = reinterpret_cast<const char *>(arg);
@@ -508,7 +532,7 @@ HANDLER(bucket_auth_handler) {
508
532
  if (!root.isArray() || root.size() != 2) {
509
533
  return LCB_ECTL_BADARG;
510
534
  }
511
- lcbauth_add_pass(instance->settings->auth,
535
+ return lcbauth_add_pass(instance->settings->auth,
512
536
  root[0].asString().c_str(),
513
537
  root[1].asString().c_str(), LCBAUTH_F_BUCKET);
514
538
  } else {
@@ -585,7 +609,12 @@ static ctl_handler handlers[] = {
585
609
  client_string_handler, /* LCB_CNTL_CLIENT_STRING */
586
610
  bucket_auth_handler, /* LCB_CNTL_BUCKET_CRED */
587
611
  timeout_common, /* LCB_CNTL_RETRY_NMV_DELAY */
588
- read_chunk_size_handler /*LCB_CNTL_READ_CHUNKSIZE */
612
+ read_chunk_size_handler, /*LCB_CNTL_READ_CHUNKSIZE */
613
+ enable_errmap_handler, /* LCB_CNTL_ENABLE_ERRMAP */
614
+ select_bucket_handler, /* LCB_CNTL_SELECT_BUCKET */
615
+ tcp_keepalive_handler, /* LCB_CNTL_TCP_KEEPALIVE */
616
+ config_poll_interval_handler, /* LCB_CNTL_CONFIG_POLL_INTERVAL */
617
+ send_hello_handler /* LCB_CNTL_SEND_HELLO */
589
618
  };
590
619
 
591
620
  /* Union used for conversion to/from string functions */
@@ -737,6 +766,11 @@ static cntl_OPCODESTRS stropcode_map[] = {
737
766
  {"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timeout},
738
767
  {"bucket_cred", LCB_CNTL_BUCKET_CRED, NULL},
739
768
  {"read_chunk_size", LCB_CNTL_READ_CHUNKSIZE, convert_u32},
769
+ {"enable_errmap", LCB_CNTL_ENABLE_ERRMAP, convert_intbool},
770
+ {"select_bucket", LCB_CNTL_SELECT_BUCKET, convert_intbool},
771
+ {"tcp_keepalive", LCB_CNTL_TCP_KEEPALIVE, convert_intbool},
772
+ {"config_poll_interval", LCB_CNTL_CONFIG_POLL_INTERVAL, convert_timeout},
773
+ {"send_hello", LCB_CNTL_SEND_HELLO, convert_intbool},
740
774
  {NULL, -1}
741
775
  };
742
776
 
@@ -31,6 +31,8 @@
31
31
  #define F_HASUSER (1<<2)
32
32
  #define F_SSLSCHEME (1<<3)
33
33
  #define F_FILEONLY (1<<4)
34
+ #define F_DNSSRV (1<<5)
35
+ #define F_DNSSRV_EXPLICIT ( (1<<6) |F_DNSSRV)
34
36
 
35
37
  using namespace lcb;
36
38
 
@@ -104,6 +106,14 @@ Connspec::parse_hosts(const char *hostbegin,
104
106
  port = scratch.substr(colonpos + 1);
105
107
  }
106
108
 
109
+ if (m_flags & F_DNSSRV_EXPLICIT) {
110
+ if (!m_hosts.empty()) {
111
+ SET_ERROR("Only a single host is allowed with DNS SRV");
112
+ } else if (!port.empty()) {
113
+ SET_ERROR("Port cannot be specified with DNS SRV");
114
+ }
115
+ }
116
+
107
117
  m_hosts.resize(m_hosts.size() + 1);
108
118
  Spechost *dh = &m_hosts.back();
109
119
  dh->hostname = scratch.substr(0, hostlen);
@@ -234,6 +244,23 @@ Connspec::parse_options(
234
244
  if (sscanf(value, "%d", &m_loglevel) != 1) {
235
245
  SET_ERROR("console_log_level must be a numeric value");
236
246
  }
247
+ } else if (!strcmp(key, "dnssrv")) {
248
+ if ((m_flags & F_DNSSRV_EXPLICIT) == F_DNSSRV_EXPLICIT) {
249
+ SET_ERROR("Cannot use dnssrv scheme with dnssrv option");
250
+ }
251
+ int btmp = 0;
252
+ if (!strcmp(value, "on") || !strcmp(value, "true")) {
253
+ btmp = 1;
254
+ } else if (!strcmp(value, "off") || !strcmp(value, "false")) {
255
+ btmp = 0;
256
+ } else if (sscanf(value, "%d", &btmp) != 1) {
257
+ SET_ERROR("dnssrv must have numeric (boolean) value");
258
+ }
259
+ if (btmp) {
260
+ m_flags |= F_DNSSRV;
261
+ } else {
262
+ m_flags &= ~F_DNSSRV_EXPLICIT;
263
+ }
237
264
  } else {
238
265
  m_ctlopts.push_back(std::make_pair(key, value));
239
266
  }
@@ -288,10 +315,17 @@ Connspec::parse(const char *connstr_, const char **errmsg)
288
315
  m_implicit_port = 0;
289
316
  } else if (SCHEME_MATCHES(LCB_SPECSCHEME_MCCOMPAT)) {
290
317
  m_implicit_port = LCB_CONFIG_MCCOMPAT_PORT;
318
+ } else if (SCHEME_MATCHES(LCB_SPECSCHEME_SRV)) {
319
+ m_implicit_port = LCB_CONFIG_MCD_PORT;
320
+ m_flags |= F_DNSSRV_EXPLICIT;
321
+ } else if (SCHEME_MATCHES(LCB_SPECSCHEME_SRV_SSL)) {
322
+ m_implicit_port = LCB_CONFIG_MCD_SSL_PORT;
323
+ m_sslopts |= LCB_SSL_ENABLED;
324
+ m_flags |= F_SSLSCHEME | F_DNSSRV_EXPLICIT;
291
325
  } else {
292
326
  /* If we don't have a scheme at all: */
293
327
  if (strstr(connstr_, "://")) {
294
- SET_ERROR("String must begin with ''couchbase://, 'couchbases://', or 'http://'");
328
+ SET_ERROR("String must begin with 'couchbase://, 'couchbases://', or 'http://'");
295
329
  } else {
296
330
  found_scheme = "";
297
331
  m_implicit_port = LCB_CONFIG_HTTP_PORT;
@@ -345,6 +379,8 @@ Connspec::parse(const char *connstr_, const char **errmsg)
345
379
  if (m_hosts.empty()) {
346
380
  m_hosts.resize(m_hosts.size()+1);
347
381
  m_hosts.back().hostname = "localhost";
382
+ } else if (m_hosts.size() == 1 && m_hosts[0].isTypeless()) {
383
+ m_flags |= F_DNSSRV;
348
384
  }
349
385
 
350
386
  if (options_ != NULL) {
@@ -352,11 +388,6 @@ Connspec::parse(const char *connstr_, const char **errmsg)
352
388
  goto GT_DONE;
353
389
  }
354
390
  }
355
-
356
- if (m_username.empty()) {
357
- m_username = m_bucket;
358
- }
359
-
360
391
  GT_DONE:
361
392
  return err;
362
393
  }
@@ -460,3 +491,13 @@ Connspec::load(const lcb_create_st& cropts)
460
491
  GT_DONE:
461
492
  return err;
462
493
  }
494
+
495
+ bool
496
+ Connspec::can_dnssrv() const {
497
+ return m_flags & F_DNSSRV;
498
+ }
499
+
500
+ bool
501
+ Connspec::is_explicit_dnssrv() const {
502
+ return (m_flags & F_DNSSRV_EXPLICIT) == F_DNSSRV_EXPLICIT;
503
+ }
@@ -20,9 +20,11 @@
20
20
 
21
21
  #include <libcouchbase/couchbase.h>
22
22
  #include "config.h"
23
+
23
24
  #include <string>
24
25
  #include <vector>
25
26
  #include <set>
27
+ #include "hostlist.h"
26
28
 
27
29
  #ifdef _MSC_VER
28
30
  /*
@@ -73,6 +75,18 @@ public:
73
75
  bool is_bs_http() const { return has_bsmode(LCB_CONFIG_TRANSPORT_HTTP); }
74
76
  bool is_bs_cccp() const { return has_bsmode(LCB_CONFIG_TRANSPORT_CCCP); }
75
77
  bool is_bs_file() const { return m_flags & LCB_CONNSPEC_F_FILEONLY; }
78
+
79
+ /**
80
+ * Whether a DNS SRV lookup can be performed on this connection string.
81
+ * @return true if a DNS SRV lookup is possible, or false if there is
82
+ * a parameter or format of the connection string preventing a lookup
83
+ */
84
+ bool can_dnssrv() const;
85
+
86
+ /**
87
+ * Whether the explicit `couchbase{s}+dnssrv` internal scheme is used
88
+ */
89
+ bool is_explicit_dnssrv() const;
76
90
  uint16_t default_port() const { return m_implicit_port; }
77
91
  const std::vector<Spechost>& hosts() const { return m_hosts; }
78
92
  const std::string& bucket() const { return m_bucket; }
@@ -83,6 +97,8 @@ public:
83
97
  const Options& options() const { return m_ctlopts; }
84
98
  unsigned loglevel() const { return m_loglevel; }
85
99
  const std::string& connstr() const { return m_connstr; }
100
+ void clear_hosts() { m_hosts.clear(); }
101
+ void add_host(const Spechost& host) { m_hosts.push_back(host); }
86
102
  private:
87
103
  Options m_ctlopts;
88
104
  std::string m_bucket;
@@ -110,7 +126,18 @@ private:
110
126
  #define LCB_SPECSCHEME_HTTP "http://"
111
127
  #define LCB_SPECSCHEME_HTTP_SSL "https-internal://"
112
128
  #define LCB_SPECSCHEME_MCCOMPAT "memcached://"
129
+ #define LCB_SPECSCHEME_SRV "couchbase+dnssrv://"
130
+ #define LCB_SPECSCHEME_SRV_SSL "couchbases+dnssrv://"
131
+
132
+ // Standalone functionality:
133
+ lcb_error_t
134
+ dnssrv_query(const char *name, Hostlist& hostlist);
135
+
136
+ Hostlist *
137
+ dnssrv_getbslist(const char *addr, bool is_ssl, lcb_error_t& errout);
138
+
113
139
  } // namespace
140
+
114
141
  #endif
115
142
 
116
143
  #ifdef _MSC_VER
@@ -0,0 +1,147 @@
1
+ #include <libcouchbase/couchbase.h>
2
+
3
+ #include "config.h"
4
+ #include "hostlist.h"
5
+ #include "connspec.h"
6
+ #include "hostlist.h"
7
+
8
+ #ifndef _WIN32
9
+ #include <string>
10
+
11
+ #ifdef HAVE_ARPA_NAMESER_H
12
+ #include <arpa/nameser.h>
13
+ #if __NAMESER < 19991006
14
+ #undef HAVE_RES_SEARCH
15
+ #endif /* __NAMESER < NNN */
16
+ #endif /* HAVE_ARPA_NAMESER_H */
17
+
18
+ #if defined(HAVE_ARPA_NAMESER_H) && defined(HAVE_RES_SEARCH)
19
+ #define CAN_SRV_LOOKUP
20
+ #include <cstdio>
21
+ #include <sys/types.h>
22
+ #include <netinet/in.h>
23
+ #include <resolv.h>
24
+
25
+ lcb_error_t
26
+ lcb::dnssrv_query(const char* name, lcb::Hostlist& hostlist)
27
+ {
28
+ ns_msg msg;
29
+
30
+ int rv = 0, nresp, ii;
31
+ lcb_U16 dns_rv;
32
+
33
+ std::vector<unsigned char> pkt(NS_PACKETSZ);
34
+ nresp = res_search(name, ns_c_in, ns_t_srv, &pkt[0], NS_PACKETSZ);
35
+ if (nresp < 0) {
36
+ return LCB_UNKNOWN_HOST;
37
+ }
38
+
39
+ rv = ns_initparse(&pkt[0], nresp, &msg);
40
+ if (rv != 0) {
41
+ return LCB_PROTOCOL_ERROR;
42
+ }
43
+
44
+ dns_rv = ns_msg_getflag(msg, ns_f_rcode);
45
+ if (dns_rv != ns_r_noerror) {
46
+ return LCB_UNKNOWN_HOST;
47
+ }
48
+
49
+ if (!ns_msg_count(msg, ns_s_an)) {
50
+ return LCB_UNKNOWN_HOST;
51
+ }
52
+
53
+ for (ii = 0; ii < ns_msg_count(msg, ns_s_an); ii++) {
54
+ lcb_U16 srv_prio, srv_weight, srv_port;
55
+ ns_rr rr;
56
+ const lcb_U8 *rdata;
57
+ size_t rdlen;
58
+
59
+ if (ns_parserr(&msg, ns_s_an, ii, &rr) != 0) {
60
+ continue;
61
+ }
62
+
63
+ if (ns_rr_type(rr) != ns_t_srv) {
64
+ continue;
65
+ }
66
+
67
+ /* Get the rdata and length fields */
68
+ rdata = ns_rr_rdata(rr);
69
+ rdlen = ns_rr_rdlen(rr);
70
+
71
+ if (rdlen < 6) {
72
+ continue;
73
+ }
74
+
75
+ #define do_get16(t) t = ns_get16(rdata); rdata += 2; rdlen -=2
76
+ do_get16(srv_prio);
77
+ do_get16(srv_weight);
78
+ do_get16(srv_port);
79
+ #undef do_get_16
80
+
81
+ (void)srv_prio; (void)srv_weight; /* Handle these in the future */
82
+ std::vector<char> dname(NS_MAXDNAME + 1);
83
+ ns_name_uncompress(
84
+ ns_msg_base(msg), ns_msg_end(msg),
85
+ rdata, &dname[0], NS_MAXDNAME);
86
+ hostlist.add(&dname[0], srv_port);
87
+ }
88
+ return LCB_SUCCESS;
89
+ }
90
+ #endif /* HAVE_RES_SEARCH */
91
+
92
+ #else
93
+ #include <windns.h>
94
+ #define CAN_SRV_LOOKUP
95
+ /* Implement via DnsQuery() */
96
+ lcb_error_t
97
+ lcb::dnssrv_query(const char *addr, Hostlist& hs)
98
+ {
99
+ DNS_STATUS status;
100
+ PDNS_RECORDA root, cur;
101
+
102
+ status = DnsQuery_A(
103
+ addr, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD*)&root, NULL);
104
+ if (status != 0) {
105
+ return LCB_UNKNOWN_HOST;
106
+ }
107
+
108
+ for (cur = root; cur; cur = cur->pNext) {
109
+ // Use the ASCII version of the DNS lookup structure
110
+ const DNS_SRV_DATAA *srv = &cur->Data.SRV;
111
+ hs.add(srv->pNameTarget, srv->wPort);
112
+ }
113
+ DnsRecordListFree(root, DnsFreeRecordList);
114
+ return LCB_SUCCESS;
115
+ }
116
+
117
+ #endif /* !WIN32 */
118
+
119
+
120
+ #ifndef CAN_SRV_LOOKUP
121
+ lcb_error_t lcb::dnssrv_query(const char *, Hostlist&) {
122
+ return LCB_CLIENT_FEATURE_UNAVAILABLE;
123
+ }
124
+ #endif
125
+
126
+ #define SVCNAME_PLAIN "_couchbase._tcp."
127
+ #define SVCNAME_SSL "_couchbases._tcp."
128
+
129
+ lcb::Hostlist*
130
+ lcb::dnssrv_getbslist(const char *addr, bool is_ssl, lcb_error_t& errp) {
131
+ std::string ss;
132
+ Hostlist *ret = new Hostlist();
133
+ ss.append(is_ssl ? SVCNAME_SSL : SVCNAME_PLAIN);
134
+ ss.append(addr);
135
+
136
+ errp = dnssrv_query(ss.c_str(), *ret);
137
+ if (errp != LCB_SUCCESS) {
138
+ delete ret;
139
+ return NULL;
140
+ }
141
+ if (ret->empty()) {
142
+ delete ret;
143
+ errp = LCB_NAMESERVER_ERROR;
144
+ return NULL;
145
+ }
146
+ return ret;
147
+ }