libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }