nutcracker 0.4.0.16 → 0.4.1.18

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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -3
  3. data/ext/nutcracker/ChangeLog +33 -8
  4. data/ext/nutcracker/Makefile.in +34 -21
  5. data/ext/nutcracker/README.md +61 -26
  6. data/ext/nutcracker/aclocal.m4 +34 -31
  7. data/ext/nutcracker/autom4te.cache/output.0 +1875 -1330
  8. data/ext/nutcracker/autom4te.cache/output.1 +1875 -1330
  9. data/ext/nutcracker/autom4te.cache/requests +232 -451
  10. data/ext/nutcracker/autom4te.cache/traces.0 +2256 -2129
  11. data/ext/nutcracker/autom4te.cache/traces.1 +73 -59
  12. data/ext/nutcracker/config.h.in +1 -2
  13. data/ext/nutcracker/config.h.in~ +333 -0
  14. data/ext/nutcracker/config/compile +1 -1
  15. data/ext/nutcracker/config/config.guess +13 -160
  16. data/ext/nutcracker/config/config.sub +25 -11
  17. data/ext/nutcracker/config/depcomp +1 -1
  18. data/ext/nutcracker/config/install-sh +170 -196
  19. data/ext/nutcracker/config/ltmain.sh +3509 -2018
  20. data/ext/nutcracker/config/missing +1 -1
  21. data/ext/nutcracker/configure +1874 -1329
  22. data/ext/nutcracker/configure.ac +3 -2
  23. data/ext/nutcracker/contrib/Makefile.in +18 -5
  24. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +832 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +1157 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/autom4te.cache/output.0 +13342 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/autom4te.cache/output.1 +14611 -0
  31. data/ext/nutcracker/{autom4te.cache → contrib/yaml-0.1.4/autom4te.cache}/output.2 +3465 -8761
  32. data/ext/nutcracker/contrib/yaml-0.1.4/autom4te.cache/requests +516 -0
  33. data/ext/nutcracker/{autom4te.cache/traces.2 → contrib/yaml-0.1.4/autom4te.cache/traces.0} +662 -698
  34. data/ext/nutcracker/contrib/yaml-0.1.4/autom4te.cache/traces.1 +577 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/autom4te.cache/traces.2 +2721 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +79 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in~ +80 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/config/compile +347 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1421 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1807 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +791 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +501 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +11147 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +215 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/config/test-driver +148 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/configure +14611 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +8369 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +437 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +124 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +99 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +600 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +1083 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  71. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  72. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  73. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  74. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  75. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  76. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  77. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  78. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  79. data/ext/nutcracker/m4/libtool.m4 +1474 -1087
  80. data/ext/nutcracker/m4/ltoptions.m4 +90 -37
  81. data/ext/nutcracker/m4/ltsugar.m4 +4 -3
  82. data/ext/nutcracker/m4/ltversion.m4 +6 -6
  83. data/ext/nutcracker/m4/lt~obsolete.m4 +4 -3
  84. data/ext/nutcracker/man/nutcracker.8 +1 -1
  85. data/ext/nutcracker/notes/memcache.md +162 -0
  86. data/ext/nutcracker/notes/recommendation.md +10 -5
  87. data/ext/nutcracker/notes/redis.md +23 -9
  88. data/ext/nutcracker/scripts/nutcracker.init +10 -0
  89. data/ext/nutcracker/scripts/nutcracker.init.debian +83 -0
  90. data/ext/nutcracker/scripts/nutcracker.spec +36 -2
  91. data/ext/nutcracker/scripts/redis-check.sh +4 -0
  92. data/ext/nutcracker/src/Makefile.am +6 -1
  93. data/ext/nutcracker/src/Makefile.in +26 -12
  94. data/ext/nutcracker/src/event/Makefile.in +19 -6
  95. data/ext/nutcracker/src/hashkit/Makefile.in +19 -6
  96. data/ext/nutcracker/src/hashkit/nc_jenkins.c +1 -1
  97. data/ext/nutcracker/src/hashkit/nc_ketama.c +3 -3
  98. data/ext/nutcracker/src/nc.c +1 -1
  99. data/ext/nutcracker/src/nc_conf.c +67 -19
  100. data/ext/nutcracker/src/nc_conf.h +9 -4
  101. data/ext/nutcracker/src/nc_connection.c +35 -2
  102. data/ext/nutcracker/src/nc_connection.h +53 -47
  103. data/ext/nutcracker/src/nc_core.c +8 -1
  104. data/ext/nutcracker/src/nc_message.c +23 -7
  105. data/ext/nutcracker/src/nc_message.h +24 -1
  106. data/ext/nutcracker/src/nc_proxy.c +14 -3
  107. data/ext/nutcracker/src/nc_rbtree.c +1 -5
  108. data/ext/nutcracker/src/nc_request.c +58 -10
  109. data/ext/nutcracker/src/nc_response.c +27 -4
  110. data/ext/nutcracker/src/nc_server.c +33 -5
  111. data/ext/nutcracker/src/nc_server.h +10 -9
  112. data/ext/nutcracker/src/nc_string.h +17 -0
  113. data/ext/nutcracker/src/nc_util.c +5 -1
  114. data/ext/nutcracker/src/proto/Makefile.in +19 -6
  115. data/ext/nutcracker/src/proto/nc_memcache.c +76 -12
  116. data/ext/nutcracker/src/proto/nc_proto.h +9 -0
  117. data/ext/nutcracker/src/proto/nc_redis.c +400 -18
  118. data/lib/nutcracker.rb +1 -1
  119. data/lib/nutcracker/version.rb +1 -1
  120. metadata +61 -6
  121. data/ext/nutcracker/notes/memcache.txt +0 -123
@@ -1,7 +1,7 @@
1
- # Makefile.in generated by automake 1.14.1 from Makefile.am.
1
+ # Makefile.in generated by automake 1.15 from Makefile.am.
2
2
  # @configure_input@
3
3
 
4
- # Copyright (C) 1994-2013 Free Software Foundation, Inc.
4
+ # Copyright (C) 1994-2014 Free Software Foundation, Inc.
5
5
 
6
6
  # This Makefile.in is free software; the Free Software Foundation
7
7
  # gives unlimited permission to copy and/or distribute it,
@@ -16,7 +16,17 @@
16
16
 
17
17
 
18
18
  VPATH = @srcdir@
19
- am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
19
+ am__is_gnu_make = { \
20
+ if test -z '$(MAKELEVEL)'; then \
21
+ false; \
22
+ elif test -n '$(MAKE_HOST)'; then \
23
+ true; \
24
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
25
+ true; \
26
+ else \
27
+ false; \
28
+ fi; \
29
+ }
20
30
  am__make_running_with_option = \
21
31
  case $${target_option-} in \
22
32
  ?) ;; \
@@ -80,8 +90,6 @@ POST_UNINSTALL = :
80
90
  build_triplet = @build@
81
91
  host_triplet = @host@
82
92
  subdir = src/hashkit
83
- DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
84
- $(top_srcdir)/config/depcomp $(noinst_HEADERS)
85
93
  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
86
94
  am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
87
95
  $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -89,6 +97,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
89
97
  $(top_srcdir)/configure.ac
90
98
  am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
91
99
  $(ACLOCAL_M4)
100
+ DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
101
+ $(am__DIST_COMMON)
92
102
  mkinstalldirs = $(install_sh) -d
93
103
  CONFIG_HEADER = $(top_builddir)/config.h
94
104
  CONFIG_CLEAN_FILES =
@@ -172,6 +182,7 @@ am__define_uniq_tagged_files = \
172
182
  done | $(am__uniquify_input)`
173
183
  ETAGS = etags
174
184
  CTAGS = ctags
185
+ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp
175
186
  DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
176
187
  ACLOCAL = @ACLOCAL@
177
188
  AMTAR = @AMTAR@
@@ -216,6 +227,7 @@ LIBTOOL = @LIBTOOL@
216
227
  LIPO = @LIPO@
217
228
  LN_S = @LN_S@
218
229
  LTLIBOBJS = @LTLIBOBJS@
230
+ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
219
231
  MAKEINFO = @MAKEINFO@
220
232
  MANIFEST_TOOL = @MANIFEST_TOOL@
221
233
  MKDIR_P = @MKDIR_P@
@@ -327,7 +339,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
327
339
  echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/hashkit/Makefile'; \
328
340
  $(am__cd) $(top_srcdir) && \
329
341
  $(AUTOMAKE) --foreign src/hashkit/Makefile
330
- .PRECIOUS: Makefile
331
342
  Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
332
343
  @case '$?' in \
333
344
  *config.status*) \
@@ -603,6 +614,8 @@ uninstall-am:
603
614
  mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
604
615
  tags tags-am uninstall uninstall-am
605
616
 
617
+ .PRECIOUS: Makefile
618
+
606
619
 
607
620
  # Tell versions [3.59,3.63) of GNU make to not export all variables.
608
621
  # Otherwise a system limit (for SysV at least) may be exceeded.
@@ -106,7 +106,7 @@ hash_jenkins(const char *key, size_t length)
106
106
  * rest of the string. Every machine with memory protection I've seen
107
107
  * does it on word boundaries, so is OK with this. But VALGRIND will
108
108
  * still catch it and complain. The masking trick does make the hash
109
- * noticably faster for short strings (like English words).
109
+ * noticeably faster for short strings (like English words).
110
110
  */
111
111
  switch(length)
112
112
  {
@@ -162,10 +162,10 @@ ketama_update(struct server_pool *pool)
162
162
  pointer_per_server = (uint32_t) ((floorf((float) (pct * KETAMA_POINTS_PER_SERVER / 4 * (float)nlive_server + 0.0000000001))) * 4);
163
163
  pointer_per_hash = 4;
164
164
 
165
- log_debug(LOG_VERB, "%.*s:%"PRIu16" weight %"PRIu32" of %"PRIu32" "
165
+ log_debug(LOG_VERB, "%.*s weight %"PRIu32" of %"PRIu32" "
166
166
  "pct %0.5f points per server %"PRIu32"",
167
- server->name.len, server->name.data, server->port,
168
- server->weight, total_weight, pct, pointer_per_server);
167
+ server->name.len, server->name.data, server->weight,
168
+ total_weight, pct, pointer_per_server);
169
169
 
170
170
  for (pointer_index = 1;
171
171
  pointer_index <= pointer_per_server / pointer_per_hash;
@@ -214,7 +214,7 @@ nc_show_usage(void)
214
214
  " -d, --daemonize : run as a daemon" CRLF
215
215
  " -D, --describe-stats : print stats description and exit");
216
216
  log_stderr(
217
- " -v, --verbosity=N : set logging level (default: %d, min: %d, max: %d)" CRLF
217
+ " -v, --verbose=N : set logging level (default: %d, min: %d, max: %d)" CRLF
218
218
  " -o, --output=S : set logging file (default: %s)" CRLF
219
219
  " -c, --conf-file=S : set configuration file (default: %s)" CRLF
220
220
  " -s, --stats-port=N : set stats monitoring port (default: %d)" CRLF
@@ -74,6 +74,14 @@ static struct command conf_commands[] = {
74
74
  conf_set_bool,
75
75
  offsetof(struct conf_pool, redis) },
76
76
 
77
+ { string("redis_auth"),
78
+ conf_set_string,
79
+ offsetof(struct conf_pool, redis_auth) },
80
+
81
+ { string("redis_db"),
82
+ conf_set_num,
83
+ offsetof(struct conf_pool, redis_db) },
84
+
77
85
  { string("preconnect"),
78
86
  conf_set_bool,
79
87
  offsetof(struct conf_pool, preconnect) },
@@ -106,6 +114,7 @@ conf_server_init(struct conf_server *cs)
106
114
  {
107
115
  string_init(&cs->pname);
108
116
  string_init(&cs->name);
117
+ string_init(&cs->addrstr);
109
118
  cs->port = 0;
110
119
  cs->weight = 0;
111
120
 
@@ -121,6 +130,7 @@ conf_server_deinit(struct conf_server *cs)
121
130
  {
122
131
  string_deinit(&cs->pname);
123
132
  string_deinit(&cs->name);
133
+ string_deinit(&cs->addrstr);
124
134
  cs->valid = 0;
125
135
  log_debug(LOG_VVERB, "deinit conf server %p", cs);
126
136
  }
@@ -142,12 +152,11 @@ conf_server_each_transform(void *elem, void *data)
142
152
 
143
153
  s->pname = cs->pname;
144
154
  s->name = cs->name;
155
+ s->addrstr = cs->addrstr;
145
156
  s->port = (uint16_t)cs->port;
146
157
  s->weight = (uint32_t)cs->weight;
147
158
 
148
- s->family = cs->info.family;
149
- s->addrlen = cs->info.addrlen;
150
- s->addr = (struct sockaddr *)&cs->info.addr;
159
+ nc_memcpy(&s->info, &cs->info, sizeof(cs->info));
151
160
 
152
161
  s->ns_conn_q = 0;
153
162
  TAILQ_INIT(&s->s_conn_q);
@@ -170,6 +179,7 @@ conf_pool_init(struct conf_pool *cp, struct string *name)
170
179
 
171
180
  string_init(&cp->listen.pname);
172
181
  string_init(&cp->listen.name);
182
+ string_init(&cp->redis_auth);
173
183
  cp->listen.port = 0;
174
184
  memset(&cp->listen.info, 0, sizeof(cp->listen.info));
175
185
  cp->listen.valid = 0;
@@ -184,6 +194,7 @@ conf_pool_init(struct conf_pool *cp, struct string *name)
184
194
  cp->client_connections = CONF_UNSET_NUM;
185
195
 
186
196
  cp->redis = CONF_UNSET_NUM;
197
+ cp->redis_db = CONF_UNSET_NUM;
187
198
  cp->preconnect = CONF_UNSET_NUM;
188
199
  cp->auto_eject_hosts = CONF_UNSET_NUM;
189
200
  cp->server_connections = CONF_UNSET_NUM;
@@ -219,6 +230,10 @@ conf_pool_deinit(struct conf_pool *cp)
219
230
  string_deinit(&cp->listen.pname);
220
231
  string_deinit(&cp->listen.name);
221
232
 
233
+ if (cp->redis_auth.len > 0) {
234
+ string_deinit(&cp->redis_auth);
235
+ }
236
+
222
237
  while (array_n(&cp->server) != 0) {
223
238
  conf_server_deinit(array_pop(&cp->server));
224
239
  }
@@ -258,9 +273,8 @@ conf_pool_each_transform(void *elem, void *data)
258
273
  sp->addrstr = cp->listen.pname;
259
274
  sp->port = (uint16_t)cp->listen.port;
260
275
 
261
- sp->family = cp->listen.info.family;
262
- sp->addrlen = cp->listen.info.addrlen;
263
- sp->addr = (struct sockaddr *)&cp->listen.info.addr;
276
+ nc_memcpy(&sp->info, &cp->listen.info, sizeof(cp->listen.info));
277
+ sp->perm = cp->listen.perm;
264
278
 
265
279
  sp->key_hash_type = cp->hash;
266
280
  sp->key_hash = hash_algos[cp->hash];
@@ -270,9 +284,12 @@ conf_pool_each_transform(void *elem, void *data)
270
284
  sp->redis = cp->redis ? 1 : 0;
271
285
  sp->timeout = cp->timeout;
272
286
  sp->backlog = cp->backlog;
287
+ sp->redis_db = cp->redis_db;
273
288
 
274
- sp->client_connections = (uint32_t)cp->client_connections;
289
+ sp->redis_auth = cp->redis_auth;
290
+ sp->require_auth = cp->redis_auth.len > 0 ? 1 : 0;
275
291
 
292
+ sp->client_connections = (uint32_t)cp->client_connections;
276
293
  sp->server_connections = (uint32_t)cp->server_connections;
277
294
  sp->server_retry_timeout = (int64_t)cp->server_retry_timeout * 1000LL;
278
295
  sp->server_failure_limit = (uint32_t)cp->server_failure_limit;
@@ -1161,7 +1178,7 @@ conf_validate_server(struct conf *cf, struct conf_pool *cp)
1161
1178
 
1162
1179
  if (string_compare(&cs1->name, &cs2->name) == 0) {
1163
1180
  log_error("conf: pool '%.*s' has servers with same name '%.*s'",
1164
- cp->name.len, cp->name.data, cs1->name.len,
1181
+ cp->name.len, cp->name.data, cs1->name.len,
1165
1182
  cs1->name.data);
1166
1183
  valid = false;
1167
1184
  break;
@@ -1211,6 +1228,10 @@ conf_validate_pool(struct conf *cf, struct conf_pool *cp)
1211
1228
  cp->redis = CONF_DEFAULT_REDIS;
1212
1229
  }
1213
1230
 
1231
+ if (cp->redis_db == CONF_UNSET_NUM) {
1232
+ cp->redis_db = CONF_DEFAULT_REDIS_DB;
1233
+ }
1234
+
1214
1235
  if (cp->preconnect == CONF_UNSET_NUM) {
1215
1236
  cp->preconnect = CONF_DEFAULT_PRECONNECT;
1216
1237
  }
@@ -1234,6 +1255,11 @@ conf_validate_pool(struct conf *cf, struct conf_pool *cp)
1234
1255
  cp->server_failure_limit = CONF_DEFAULT_SERVER_FAILURE_LIMIT;
1235
1256
  }
1236
1257
 
1258
+ if (!cp->redis && cp->redis_auth.len > 0) {
1259
+ log_error("conf: directive \"redis_auth:\" is only valid for a redis pool");
1260
+ return NC_ERROR;
1261
+ }
1262
+
1237
1263
  status = conf_validate_server(cf, cp);
1238
1264
  if (status != NC_OK) {
1239
1265
  return status;
@@ -1420,8 +1446,32 @@ conf_set_listen(struct conf *cf, struct command *cmd, void *conf)
1420
1446
  }
1421
1447
 
1422
1448
  if (value->data[0] == '/') {
1423
- name = value->data;
1424
- namelen = value->len;
1449
+ uint8_t *q, *start, *perm;
1450
+ uint32_t permlen;
1451
+
1452
+
1453
+ /* parse "socket_path permissions" from the end */
1454
+ p = value->data + value->len -1;
1455
+ start = value->data;
1456
+ q = nc_strrchr(p, start, ' ');
1457
+ if (q == NULL) {
1458
+ /* no permissions field, so use defaults */
1459
+ name = value->data;
1460
+ namelen = value->len;
1461
+ } else {
1462
+ perm = q + 1;
1463
+ permlen = (uint32_t)(p - perm + 1);
1464
+
1465
+ p = q - 1;
1466
+ name = start;
1467
+ namelen = (uint32_t)(p - start + 1);
1468
+
1469
+ errno = 0;
1470
+ field->perm = (mode_t)strtol((char *)perm, NULL, 8);
1471
+ if (errno || field->perm > 0777) {
1472
+ return "has an invalid file permission in \"socket_path permission\" format string";
1473
+ }
1474
+ }
1425
1475
  } else {
1426
1476
  uint8_t *q, *start, *port;
1427
1477
  uint32_t portlen;
@@ -1473,10 +1523,8 @@ conf_add_server(struct conf *cf, struct command *cmd, void *conf)
1473
1523
  uint8_t *p, *q, *start;
1474
1524
  uint8_t *pname, *addr, *port, *weight, *name;
1475
1525
  uint32_t k, delimlen, pnamelen, addrlen, portlen, weightlen, namelen;
1476
- struct string address;
1477
1526
  char delim[] = " ::";
1478
1527
 
1479
- string_init(&address);
1480
1528
  p = conf;
1481
1529
  a = (struct array *)(p + cmd->offset);
1482
1530
 
@@ -1588,18 +1636,18 @@ conf_add_server(struct conf *cf, struct command *cmd, void *conf)
1588
1636
  return CONF_ERROR;
1589
1637
  }
1590
1638
 
1591
- status = string_copy(&address, addr, addrlen);
1639
+ status = string_copy(&field->addrstr, addr, addrlen);
1592
1640
  if (status != NC_OK) {
1593
1641
  return CONF_ERROR;
1594
1642
  }
1595
1643
 
1596
- status = nc_resolve(&address, field->port, &field->info);
1597
- if (status != NC_OK) {
1598
- string_deinit(&address);
1599
- return CONF_ERROR;
1600
- }
1644
+ /*
1645
+ * The address resolution of the backend server hostname is lazy.
1646
+ * The resolution occurs when a new connection to the server is
1647
+ * created, which could either be the first time or every time
1648
+ * the server gets re-added to the pool after an auto ejection
1649
+ */
1601
1650
 
1602
- string_deinit(&address);
1603
1651
  field->valid = 1;
1604
1652
 
1605
1653
  return CONF_OK;
@@ -47,6 +47,7 @@
47
47
  #define CONF_DEFAULT_LISTEN_BACKLOG 512
48
48
  #define CONF_DEFAULT_CLIENT_CONNECTIONS 0
49
49
  #define CONF_DEFAULT_REDIS false
50
+ #define CONF_DEFAULT_REDIS_DB 0
50
51
  #define CONF_DEFAULT_PRECONNECT false
51
52
  #define CONF_DEFAULT_AUTO_EJECT_HOSTS false
52
53
  #define CONF_DEFAULT_SERVER_RETRY_TIMEOUT 30 * 1000 /* in msec */
@@ -55,16 +56,18 @@
55
56
  #define CONF_DEFAULT_KETAMA_PORT 11211
56
57
 
57
58
  struct conf_listen {
58
- struct string pname; /* listen: as "name:port" */
59
- struct string name; /* name */
59
+ struct string pname; /* listen: as "hostname:port" */
60
+ struct string name; /* hostname:port */
60
61
  int port; /* port */
62
+ mode_t perm; /* socket permissions */
61
63
  struct sockinfo info; /* listen socket info */
62
64
  unsigned valid:1; /* valid? */
63
65
  };
64
66
 
65
67
  struct conf_server {
66
- struct string pname; /* server: as "name:port:weight" */
67
- struct string name; /* name */
68
+ struct string pname; /* server: as "hostname:port:weight" */
69
+ struct string name; /* hostname:port or [name] */
70
+ struct string addrstr; /* hostname */
68
71
  int port; /* port */
69
72
  int weight; /* weight */
70
73
  struct sockinfo info; /* connect socket info */
@@ -81,6 +84,8 @@ struct conf_pool {
81
84
  int backlog; /* backlog: */
82
85
  int client_connections; /* client_connections: */
83
86
  int redis; /* redis: */
87
+ struct string redis_auth; /* redis_auth: redis auth password (matches requirepass on redis) */
88
+ int redis_db; /* redis_db: redis db */
84
89
  int preconnect; /* preconnect: */
85
90
  int auto_eject_hosts; /* auto_eject_hosts: */
86
91
  int server_connections; /* server_connections: */
@@ -156,6 +156,7 @@ _conn_get(void)
156
156
  conn->eof = 0;
157
157
  conn->done = 0;
158
158
  conn->redis = 0;
159
+ conn->authenticated = 0;
159
160
 
160
161
  ntotal_conn++;
161
162
  ncurr_conn++;
@@ -201,7 +202,9 @@ conn_get(void *owner, bool client, bool redis)
201
202
  conn->dequeue_inq = NULL;
202
203
  conn->enqueue_outq = req_client_enqueue_omsgq;
203
204
  conn->dequeue_outq = req_client_dequeue_omsgq;
204
-
205
+ conn->post_connect = NULL;
206
+ conn->swallow_msg = NULL;
207
+
205
208
  ncurr_cconn++;
206
209
  } else {
207
210
  /*
@@ -226,10 +229,16 @@ conn_get(void *owner, bool client, bool redis)
226
229
  conn->dequeue_inq = req_server_dequeue_imsgq;
227
230
  conn->enqueue_outq = req_server_enqueue_omsgq;
228
231
  conn->dequeue_outq = req_server_dequeue_omsgq;
232
+ if (redis) {
233
+ conn->post_connect = redis_post_connect;
234
+ conn->swallow_msg = redis_swallow_msg;
235
+ } else {
236
+ conn->post_connect = memcache_post_connect;
237
+ conn->swallow_msg = memcache_swallow_msg;
238
+ }
229
239
  }
230
240
 
231
241
  conn->ref(conn, owner);
232
-
233
242
  log_debug(LOG_VVERB, "get conn %p client %d", conn, conn->client);
234
243
 
235
244
  return conn;
@@ -438,3 +447,27 @@ conn_ncurr_cconn(void)
438
447
  {
439
448
  return ncurr_cconn;
440
449
  }
450
+
451
+ /*
452
+ * Returns true if the connection is authenticated or doesn't require
453
+ * authentication, otherwise return false
454
+ */
455
+ bool
456
+ conn_authenticated(struct conn *conn)
457
+ {
458
+ struct server_pool *pool;
459
+
460
+ ASSERT(!conn->proxy);
461
+
462
+ pool = conn->client ? conn->owner : ((struct server *)conn->owner)->owner;
463
+
464
+ if (!pool->require_auth) {
465
+ return true;
466
+ }
467
+
468
+ if (!conn->authenticated) {
469
+ return false;
470
+ }
471
+
472
+ return true;
473
+ }
@@ -35,55 +35,60 @@ typedef void (*conn_ref_t)(struct conn *, void *);
35
35
  typedef void (*conn_unref_t)(struct conn *);
36
36
 
37
37
  typedef void (*conn_msgq_t)(struct context *, struct conn *, struct msg *);
38
+ typedef void (*conn_post_connect_t)(struct context *ctx, struct conn *, struct server *server);
39
+ typedef void (*conn_swallow_msg_t)(struct conn *, struct msg *, struct msg *);
38
40
 
39
41
  struct conn {
40
- TAILQ_ENTRY(conn) conn_tqe; /* link in server_pool / server / free q */
41
- void *owner; /* connection owner - server_pool / server */
42
-
43
- int sd; /* socket descriptor */
44
- int family; /* socket address family */
45
- socklen_t addrlen; /* socket length */
46
- struct sockaddr *addr; /* socket address (ref in server or server_pool) */
47
-
48
- struct msg_tqh imsg_q; /* incoming request Q */
49
- struct msg_tqh omsg_q; /* outstanding request Q */
50
- struct msg *rmsg; /* current message being rcvd */
51
- struct msg *smsg; /* current message being sent */
52
-
53
- conn_recv_t recv; /* recv (read) handler */
54
- conn_recv_next_t recv_next; /* recv next message handler */
55
- conn_recv_done_t recv_done; /* read done handler */
56
- conn_send_t send; /* send (write) handler */
57
- conn_send_next_t send_next; /* write next message handler */
58
- conn_send_done_t send_done; /* write done handler */
59
- conn_close_t close; /* close handler */
60
- conn_active_t active; /* active? handler */
61
-
62
- conn_ref_t ref; /* connection reference handler */
63
- conn_unref_t unref; /* connection unreference handler */
64
-
65
- conn_msgq_t enqueue_inq; /* connection inq msg enqueue handler */
66
- conn_msgq_t dequeue_inq; /* connection inq msg dequeue handler */
67
- conn_msgq_t enqueue_outq; /* connection outq msg enqueue handler */
68
- conn_msgq_t dequeue_outq; /* connection outq msg dequeue handler */
69
-
70
- size_t recv_bytes; /* received (read) bytes */
71
- size_t send_bytes; /* sent (written) bytes */
72
-
73
- uint32_t events; /* connection io events */
74
- err_t err; /* connection errno */
75
- unsigned recv_active:1; /* recv active? */
76
- unsigned recv_ready:1; /* recv ready? */
77
- unsigned send_active:1; /* send active? */
78
- unsigned send_ready:1; /* send ready? */
79
-
80
- unsigned client:1; /* client? or server? */
81
- unsigned proxy:1; /* proxy? */
82
- unsigned connecting:1; /* connecting? */
83
- unsigned connected:1; /* connected? */
84
- unsigned eof:1; /* eof? aka passive close? */
85
- unsigned done:1; /* done? aka close? */
86
- unsigned redis:1; /* redis? */
42
+ TAILQ_ENTRY(conn) conn_tqe; /* link in server_pool / server / free q */
43
+ void *owner; /* connection owner - server_pool / server */
44
+
45
+ int sd; /* socket descriptor */
46
+ int family; /* socket address family */
47
+ socklen_t addrlen; /* socket length */
48
+ struct sockaddr *addr; /* socket address (ref in server or server_pool) */
49
+
50
+ struct msg_tqh imsg_q; /* incoming request Q */
51
+ struct msg_tqh omsg_q; /* outstanding request Q */
52
+ struct msg *rmsg; /* current message being rcvd */
53
+ struct msg *smsg; /* current message being sent */
54
+
55
+ conn_recv_t recv; /* recv (read) handler */
56
+ conn_recv_next_t recv_next; /* recv next message handler */
57
+ conn_recv_done_t recv_done; /* read done handler */
58
+ conn_send_t send; /* send (write) handler */
59
+ conn_send_next_t send_next; /* write next message handler */
60
+ conn_send_done_t send_done; /* write done handler */
61
+ conn_close_t close; /* close handler */
62
+ conn_active_t active; /* active? handler */
63
+ conn_post_connect_t post_connect; /* post connect handler */
64
+ conn_swallow_msg_t swallow_msg; /* react on messages to be swallowed */
65
+
66
+ conn_ref_t ref; /* connection reference handler */
67
+ conn_unref_t unref; /* connection unreference handler */
68
+
69
+ conn_msgq_t enqueue_inq; /* connection inq msg enqueue handler */
70
+ conn_msgq_t dequeue_inq; /* connection inq msg dequeue handler */
71
+ conn_msgq_t enqueue_outq; /* connection outq msg enqueue handler */
72
+ conn_msgq_t dequeue_outq; /* connection outq msg dequeue handler */
73
+
74
+ size_t recv_bytes; /* received (read) bytes */
75
+ size_t send_bytes; /* sent (written) bytes */
76
+
77
+ uint32_t events; /* connection io events */
78
+ err_t err; /* connection errno */
79
+ unsigned recv_active:1; /* recv active? */
80
+ unsigned recv_ready:1; /* recv ready? */
81
+ unsigned send_active:1; /* send active? */
82
+ unsigned send_ready:1; /* send ready? */
83
+
84
+ unsigned client:1; /* client? or server? */
85
+ unsigned proxy:1; /* proxy? */
86
+ unsigned connecting:1; /* connecting? */
87
+ unsigned connected:1; /* connected? */
88
+ unsigned eof:1; /* eof? aka passive close? */
89
+ unsigned done:1; /* done? aka close? */
90
+ unsigned redis:1; /* redis? */
91
+ unsigned authenticated:1; /* authenticated? */
87
92
  };
88
93
 
89
94
  TAILQ_HEAD(conn_tqh, conn);
@@ -99,5 +104,6 @@ void conn_deinit(void);
99
104
  uint32_t conn_ncurr_conn(void);
100
105
  uint64_t conn_ntotal_conn(void);
101
106
  uint32_t conn_ncurr_cconn(void);
107
+ bool conn_authenticated(struct conn *conn);
102
108
 
103
109
  #endif