nginxtra 1.0.15.0 → 1.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/VERSION +1 -1
  2. data/bin/nginxtra +1 -1
  3. data/lib/nginxtra/action.rb +10 -0
  4. data/lib/nginxtra/actions/compile.rb +16 -2
  5. data/lib/nginxtra/actions/start.rb +18 -2
  6. data/lib/nginxtra/actions/status.rb +1 -10
  7. data/lib/nginxtra/actions/stop.rb +18 -0
  8. data/lib/nginxtra/cli.rb +12 -3
  9. data/lib/nginxtra/config.rb +10 -0
  10. data/src/nginx/CHANGES +311 -90
  11. data/src/nginx/CHANGES.ru +315 -88
  12. data/src/nginx/auto/lib/pcre/conf +22 -5
  13. data/src/nginx/auto/lib/pcre/make +1 -1
  14. data/src/nginx/auto/modules +14 -3
  15. data/src/nginx/auto/options +17 -3
  16. data/src/nginx/auto/os/freebsd +8 -0
  17. data/src/nginx/auto/os/linux +5 -4
  18. data/src/nginx/auto/os/solaris +2 -1
  19. data/src/nginx/auto/sources +10 -2
  20. data/src/nginx/auto/summary +2 -0
  21. data/src/nginx/auto/types/sizeof +2 -1
  22. data/src/nginx/auto/types/typedef +1 -1
  23. data/src/nginx/auto/types/uintptr_t +7 -4
  24. data/src/nginx/auto/unix +82 -21
  25. data/src/nginx/conf/fastcgi.conf +1 -0
  26. data/src/nginx/conf/fastcgi_params +1 -0
  27. data/src/nginx/conf/scgi_params +1 -0
  28. data/src/nginx/conf/uwsgi_params +1 -0
  29. data/src/nginx/man/nginx.8 +49 -49
  30. data/src/nginx/src/core/nginx.c +10 -12
  31. data/src/nginx/src/core/nginx.h +2 -2
  32. data/src/nginx/src/core/ngx_buf.c +9 -7
  33. data/src/nginx/src/core/ngx_buf.h +2 -2
  34. data/src/nginx/src/core/ngx_conf_file.c +4 -11
  35. data/src/nginx/src/core/ngx_conf_file.h +1 -1
  36. data/src/nginx/src/core/ngx_connection.c +52 -1
  37. data/src/nginx/src/core/ngx_connection.h +6 -0
  38. data/src/nginx/src/core/ngx_core.h +5 -0
  39. data/src/nginx/src/core/ngx_cycle.c +1 -1
  40. data/src/nginx/src/core/ngx_cycle.h +2 -2
  41. data/src/nginx/src/core/ngx_file.c +1 -1
  42. data/src/nginx/src/core/ngx_inet.c +11 -8
  43. data/src/nginx/src/core/ngx_murmurhash.h +1 -1
  44. data/src/nginx/src/core/ngx_open_file_cache.c +343 -38
  45. data/src/nginx/src/core/ngx_open_file_cache.h +10 -0
  46. data/src/nginx/src/core/ngx_output_chain.c +2 -1
  47. data/src/nginx/src/core/ngx_parse.h +0 -3
  48. data/src/nginx/src/core/ngx_rbtree.c +1 -2
  49. data/src/nginx/src/core/ngx_regex.c +263 -5
  50. data/src/nginx/src/core/ngx_regex.h +6 -2
  51. data/src/nginx/src/core/ngx_resolver.c +88 -21
  52. data/src/nginx/src/core/ngx_resolver.h +7 -8
  53. data/src/nginx/src/core/ngx_shmtx.c +69 -44
  54. data/src/nginx/src/core/ngx_shmtx.h +12 -1
  55. data/src/nginx/src/core/ngx_slab.c +3 -3
  56. data/src/nginx/src/core/ngx_slab.h +1 -1
  57. data/src/nginx/src/core/ngx_string.c +19 -16
  58. data/src/nginx/src/core/ngx_times.c +2 -2
  59. data/src/nginx/src/event/modules/ngx_epoll_module.c +2 -2
  60. data/src/nginx/src/event/modules/ngx_eventport_module.c +1 -1
  61. data/src/nginx/src/event/modules/ngx_kqueue_module.c +1 -1
  62. data/src/nginx/src/event/ngx_event.c +25 -17
  63. data/src/nginx/src/event/ngx_event_openssl.c +3 -1
  64. data/src/nginx/src/event/ngx_event_pipe.c +108 -85
  65. data/src/nginx/src/event/ngx_event_pipe.h +1 -2
  66. data/src/nginx/src/event/ngx_event_timer.c +2 -3
  67. data/src/nginx/src/http/modules/ngx_http_access_module.c +9 -4
  68. data/src/nginx/src/http/modules/ngx_http_browser_module.c +5 -3
  69. data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -1
  70. data/src/nginx/src/http/modules/ngx_http_degradation_module.c +1 -1
  71. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +144 -22
  72. data/src/nginx/src/http/modules/ngx_http_flv_module.c +8 -0
  73. data/src/nginx/src/http/modules/ngx_http_geo_module.c +3 -3
  74. data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +20 -6
  75. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +8 -0
  76. data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +23 -27
  77. data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -3
  78. data/src/nginx/src/http/modules/ngx_http_index_module.c +24 -0
  79. data/src/nginx/src/http/modules/ngx_http_limit_conn_module.c +747 -0
  80. data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +289 -133
  81. data/src/nginx/src/http/modules/ngx_http_log_module.c +34 -6
  82. data/src/nginx/src/http/modules/ngx_http_memcached_module.c +19 -3
  83. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +8 -0
  84. data/src/nginx/src/http/modules/ngx_http_proxy_module.c +1446 -239
  85. data/src/nginx/src/http/modules/ngx_http_realip_module.c +4 -10
  86. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +90 -21
  87. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +8 -11
  88. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +16 -6
  89. data/src/nginx/src/http/modules/ngx_http_static_module.c +8 -0
  90. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +2 -2
  91. data/src/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +570 -0
  92. data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +1 -5
  93. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +77 -26
  94. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +171 -37
  95. data/src/nginx/src/http/modules/perl/nginx.pm +2 -1
  96. data/src/nginx/src/http/modules/perl/nginx.xs +4 -0
  97. data/src/nginx/src/http/ngx_http.c +8 -1
  98. data/src/nginx/src/http/ngx_http.h +1 -0
  99. data/src/nginx/src/http/ngx_http_busy_lock.c +2 -2
  100. data/src/nginx/src/http/ngx_http_cache.h +12 -1
  101. data/src/nginx/src/http/ngx_http_copy_filter_module.c +4 -3
  102. data/src/nginx/src/http/ngx_http_core_module.c +303 -37
  103. data/src/nginx/src/http/ngx_http_core_module.h +15 -0
  104. data/src/nginx/src/http/ngx_http_file_cache.c +226 -52
  105. data/src/nginx/src/http/ngx_http_parse.c +69 -3
  106. data/src/nginx/src/http/ngx_http_postpone_filter_module.c +4 -4
  107. data/src/nginx/src/http/ngx_http_request.c +61 -27
  108. data/src/nginx/src/http/ngx_http_request.h +3 -3
  109. data/src/nginx/src/http/ngx_http_request_body.c +1 -1
  110. data/src/nginx/src/http/ngx_http_script.c +6 -0
  111. data/src/nginx/src/http/ngx_http_upstream.c +200 -47
  112. data/src/nginx/src/http/ngx_http_upstream.h +20 -1
  113. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +22 -6
  114. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +1 -0
  115. data/src/nginx/src/http/ngx_http_variables.c +123 -4
  116. data/src/nginx/src/mail/ngx_mail.c +13 -0
  117. data/src/nginx/src/mail/ngx_mail.h +12 -0
  118. data/src/nginx/src/mail/ngx_mail_core_module.c +100 -15
  119. data/src/nginx/src/os/unix/ngx_daemon.c +2 -1
  120. data/src/nginx/src/os/unix/ngx_darwin.h +3 -0
  121. data/src/nginx/src/os/unix/ngx_darwin_config.h +1 -0
  122. data/src/nginx/src/os/unix/ngx_darwin_init.c +30 -0
  123. data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +11 -5
  124. data/src/nginx/src/os/unix/ngx_errno.h +5 -0
  125. data/src/nginx/src/os/unix/ngx_files.h +50 -1
  126. data/src/nginx/src/os/unix/ngx_freebsd.h +2 -1
  127. data/src/nginx/src/os/unix/ngx_freebsd_config.h +2 -0
  128. data/src/nginx/src/os/unix/ngx_freebsd_init.c +4 -3
  129. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +2 -2
  130. data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +12 -6
  131. data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +1 -1
  132. data/src/nginx/src/os/unix/ngx_linux_config.h +1 -0
  133. data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +6 -4
  134. data/src/nginx/src/os/unix/ngx_os.h +0 -1
  135. data/src/nginx/src/os/unix/ngx_posix_config.h +3 -0
  136. data/src/nginx/src/os/unix/ngx_process.c +50 -11
  137. data/src/nginx/src/os/unix/ngx_process.h +1 -0
  138. data/src/nginx/src/os/unix/ngx_process_cycle.c +6 -15
  139. data/src/nginx/src/os/unix/ngx_readv_chain.c +8 -0
  140. data/src/nginx/src/os/unix/ngx_setaffinity.c +69 -0
  141. data/src/nginx/src/os/unix/ngx_setaffinity.h +23 -0
  142. data/src/nginx/src/os/unix/ngx_setproctitle.c +1 -1
  143. data/src/nginx/src/os/unix/ngx_solaris_config.h +2 -0
  144. data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +11 -3
  145. data/src/nginx/src/os/unix/ngx_writev_chain.c +7 -3
  146. metadata +7 -4
  147. data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +0 -553
@@ -32,6 +32,11 @@ typedef struct {
32
32
 
33
33
  ngx_uint_t min_uses;
34
34
 
35
+ #if (NGX_HAVE_OPENAT)
36
+ size_t disable_symlinks_from;
37
+ unsigned disable_symlinks:2;
38
+ #endif
39
+
35
40
  unsigned test_dir:1;
36
41
  unsigned test_only:1;
37
42
  unsigned log:1;
@@ -64,6 +69,11 @@ struct ngx_cached_open_file_s {
64
69
 
65
70
  uint32_t uses;
66
71
 
72
+ #if (NGX_HAVE_OPENAT)
73
+ size_t disable_symlinks_from;
74
+ unsigned disable_symlinks:2;
75
+ #endif
76
+
67
77
  unsigned count:24;
68
78
  unsigned close:1;
69
79
  unsigned use_event:1;
@@ -209,7 +209,8 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
209
209
  return last;
210
210
  }
211
211
 
212
- ngx_chain_update_chains(&ctx->free, &ctx->busy, &out, ctx->tag);
212
+ ngx_chain_update_chains(ctx->pool, &ctx->free, &ctx->busy, &out,
213
+ ctx->tag);
213
214
  last_out = &out;
214
215
  }
215
216
  }
@@ -13,9 +13,6 @@
13
13
  #include <ngx_core.h>
14
14
 
15
15
 
16
- #define NGX_PARSE_LARGE_TIME -2
17
-
18
-
19
16
  ssize_t ngx_parse_size(ngx_str_t *line);
20
17
  off_t ngx_parse_offset(ngx_str_t *line);
21
18
  ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec);
@@ -136,8 +136,7 @@ ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node,
136
136
 
137
137
  /* node->key < temp->key */
138
138
 
139
- p = ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key
140
- < 0)
139
+ p = ((ngx_rbtree_key_int_t) (node->key - temp->key) < 0)
141
140
  ? &temp->left : &temp->right;
142
141
 
143
142
  if (*p == sentinel) {
@@ -9,11 +9,64 @@
9
9
  #include <ngx_core.h>
10
10
 
11
11
 
12
+ typedef struct {
13
+ ngx_flag_t pcre_jit;
14
+ } ngx_regex_conf_t;
15
+
16
+
12
17
  static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
13
18
  static void ngx_libc_cdecl ngx_regex_free(void *p);
19
+ #if (NGX_HAVE_PCRE_JIT)
20
+ static void ngx_pcre_free_studies(void *data);
21
+ #endif
22
+
23
+ static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
24
+
25
+ static void *ngx_regex_create_conf(ngx_cycle_t *cycle);
26
+ static char *ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf);
27
+
28
+ static char *ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data);
29
+ static ngx_conf_post_t ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
30
+
31
+
32
+ static ngx_command_t ngx_regex_commands[] = {
33
+
34
+ { ngx_string("pcre_jit"),
35
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
36
+ ngx_conf_set_flag_slot,
37
+ 0,
38
+ offsetof(ngx_regex_conf_t, pcre_jit),
39
+ &ngx_regex_pcre_jit_post },
40
+
41
+ ngx_null_command
42
+ };
43
+
44
+
45
+ static ngx_core_module_t ngx_regex_module_ctx = {
46
+ ngx_string("regex"),
47
+ ngx_regex_create_conf,
48
+ ngx_regex_init_conf
49
+ };
50
+
51
+
52
+ ngx_module_t ngx_regex_module = {
53
+ NGX_MODULE_V1,
54
+ &ngx_regex_module_ctx, /* module context */
55
+ ngx_regex_commands, /* module directives */
56
+ NGX_CORE_MODULE, /* module type */
57
+ NULL, /* init master */
58
+ ngx_regex_module_init, /* init module */
59
+ NULL, /* init process */
60
+ NULL, /* init thread */
61
+ NULL, /* exit thread */
62
+ NULL, /* exit process */
63
+ NULL, /* exit master */
64
+ NGX_MODULE_V1_PADDING
65
+ };
14
66
 
15
67
 
16
68
  static ngx_pool_t *ngx_pcre_pool;
69
+ static ngx_list_t *ngx_pcre_studies;
17
70
 
18
71
 
19
72
  void
@@ -63,10 +116,11 @@ ngx_regex_malloc_done(void)
63
116
  ngx_int_t
64
117
  ngx_regex_compile(ngx_regex_compile_t *rc)
65
118
  {
66
- int n, erroff;
67
- char *p;
68
- const char *errstr;
69
- ngx_regex_t *re;
119
+ int n, erroff;
120
+ char *p;
121
+ pcre *re;
122
+ const char *errstr;
123
+ ngx_regex_elt_t *elt;
70
124
 
71
125
  ngx_regex_malloc_init(rc->pool);
72
126
 
@@ -93,7 +147,24 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
93
147
  return NGX_ERROR;
94
148
  }
95
149
 
96
- rc->regex = re;
150
+ rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
151
+ if (rc->regex == NULL) {
152
+ return NGX_ERROR;
153
+ }
154
+
155
+ rc->regex->pcre = re;
156
+
157
+ /* do not study at runtime */
158
+
159
+ if (ngx_pcre_studies != NULL) {
160
+ elt = ngx_list_push(ngx_pcre_studies);
161
+ if (elt == NULL) {
162
+ return NGX_ERROR;
163
+ }
164
+
165
+ elt->regex = rc->regex;
166
+ elt->name = rc->pattern.data;
167
+ }
97
168
 
98
169
  n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
99
170
  if (n < 0) {
@@ -204,3 +275,190 @@ ngx_regex_free(void *p)
204
275
  {
205
276
  return;
206
277
  }
278
+
279
+
280
+ #if (NGX_HAVE_PCRE_JIT)
281
+
282
+ static void
283
+ ngx_pcre_free_studies(void *data)
284
+ {
285
+ ngx_list_t *studies = data;
286
+
287
+ ngx_uint_t i;
288
+ ngx_list_part_t *part;
289
+ ngx_regex_elt_t *elts;
290
+
291
+ part = &studies->part;
292
+ elts = part->elts;
293
+
294
+ for (i = 0 ; /* void */ ; i++) {
295
+
296
+ if (i >= part->nelts) {
297
+ if (part->next == NULL) {
298
+ break;
299
+ }
300
+
301
+ part = part->next;
302
+ elts = part->elts;
303
+ i = 0;
304
+ }
305
+
306
+ if (elts[i].regex->extra != NULL) {
307
+ pcre_free_study(elts[i].regex->extra);
308
+ }
309
+ }
310
+ }
311
+
312
+ #endif
313
+
314
+
315
+ static ngx_int_t
316
+ ngx_regex_module_init(ngx_cycle_t *cycle)
317
+ {
318
+ int opt;
319
+ const char *errstr;
320
+ ngx_uint_t i;
321
+ ngx_list_part_t *part;
322
+ ngx_regex_elt_t *elts;
323
+
324
+ opt = 0;
325
+
326
+ #if (NGX_HAVE_PCRE_JIT)
327
+ {
328
+ ngx_regex_conf_t *rcf;
329
+ ngx_pool_cleanup_t *cln;
330
+
331
+ rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
332
+
333
+ if (rcf->pcre_jit) {
334
+ opt = PCRE_STUDY_JIT_COMPILE;
335
+
336
+ /*
337
+ * The PCRE JIT compiler uses mmap for its executable codes, so we
338
+ * have to explicitly call the pcre_free_study() function to free
339
+ * this memory.
340
+ */
341
+
342
+ cln = ngx_pool_cleanup_add(cycle->pool, 0);
343
+ if (cln == NULL) {
344
+ return NGX_ERROR;
345
+ }
346
+
347
+ cln->handler = ngx_pcre_free_studies;
348
+ cln->data = ngx_pcre_studies;
349
+ }
350
+ }
351
+ #endif
352
+
353
+ ngx_regex_malloc_init(cycle->pool);
354
+
355
+ part = &ngx_pcre_studies->part;
356
+ elts = part->elts;
357
+
358
+ for (i = 0 ; /* void */ ; i++) {
359
+
360
+ if (i >= part->nelts) {
361
+ if (part->next == NULL) {
362
+ break;
363
+ }
364
+
365
+ part = part->next;
366
+ elts = part->elts;
367
+ i = 0;
368
+ }
369
+
370
+ elts[i].regex->extra = pcre_study(elts[i].regex->pcre, opt, &errstr);
371
+
372
+ if (errstr != NULL) {
373
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
374
+ "pcre_study() failed: %s in \"%s\"",
375
+ errstr, elts[i].name);
376
+ }
377
+
378
+ #if (NGX_HAVE_PCRE_JIT)
379
+ if (opt & PCRE_STUDY_JIT_COMPILE) {
380
+ int jit, n;
381
+
382
+ jit = 0;
383
+ n = pcre_fullinfo(elts[i].regex->pcre, elts[i].regex->extra,
384
+ PCRE_INFO_JIT, &jit);
385
+
386
+ if (n != 0 || jit != 1) {
387
+ ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
388
+ "JIT compiler does not support pattern: \"%s\"",
389
+ elts[i].name);
390
+ }
391
+ }
392
+ #endif
393
+ }
394
+
395
+ ngx_regex_malloc_done();
396
+
397
+ ngx_pcre_studies = NULL;
398
+
399
+ return NGX_OK;
400
+ }
401
+
402
+
403
+ static void *
404
+ ngx_regex_create_conf(ngx_cycle_t *cycle)
405
+ {
406
+ ngx_regex_conf_t *rcf;
407
+
408
+ rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
409
+ if (rcf == NULL) {
410
+ return NULL;
411
+ }
412
+
413
+ rcf->pcre_jit = NGX_CONF_UNSET;
414
+
415
+ ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
416
+ if (ngx_pcre_studies == NULL) {
417
+ return NULL;
418
+ }
419
+
420
+ return rcf;
421
+ }
422
+
423
+
424
+ static char *
425
+ ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
426
+ {
427
+ ngx_regex_conf_t *rcf = conf;
428
+
429
+ ngx_conf_init_value(rcf->pcre_jit, 0);
430
+
431
+ return NGX_CONF_OK;
432
+ }
433
+
434
+
435
+ static char *
436
+ ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
437
+ {
438
+ ngx_flag_t *fp = data;
439
+
440
+ if (*fp == 0) {
441
+ return NGX_CONF_OK;
442
+ }
443
+
444
+ #if (NGX_HAVE_PCRE_JIT)
445
+ {
446
+ int jit, r;
447
+
448
+ jit = 0;
449
+ r = pcre_config(PCRE_CONFIG_JIT, &jit);
450
+
451
+ if (r != 0 || jit != 1) {
452
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
453
+ "PCRE library does not support JIT");
454
+ *fp = 0;
455
+ }
456
+ }
457
+ #else
458
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
459
+ "nginx was built without PCRE JIT support");
460
+ *fp = 0;
461
+ #endif
462
+
463
+ return NGX_CONF_OK;
464
+ }
@@ -19,7 +19,11 @@
19
19
 
20
20
  #define NGX_REGEX_CASELESS PCRE_CASELESS
21
21
 
22
- typedef pcre ngx_regex_t;
22
+
23
+ typedef struct {
24
+ pcre *pcre;
25
+ pcre_extra *extra;
26
+ } ngx_regex_t;
23
27
 
24
28
 
25
29
  typedef struct {
@@ -46,7 +50,7 @@ void ngx_regex_init(void);
46
50
  ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
47
51
 
48
52
  #define ngx_regex_exec(re, s, captures, size) \
49
- pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \
53
+ pcre_exec(re->pcre, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
50
54
  captures, size)
51
55
  #define ngx_regex_exec_n "pcre_exec()"
52
56
 
@@ -92,8 +92,11 @@ static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
92
92
 
93
93
 
94
94
  ngx_resolver_t *
95
- ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr)
95
+ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
96
96
  {
97
+ ngx_str_t s;
98
+ ngx_url_t u;
99
+ ngx_uint_t i;
97
100
  ngx_resolver_t *r;
98
101
  ngx_pool_cleanup_t *cln;
99
102
  ngx_udp_connection_t *uc;
@@ -110,6 +113,15 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr)
110
113
  return NULL;
111
114
  }
112
115
 
116
+ if (n) {
117
+ if (ngx_array_init(&r->udp_connections, cf->pool, n,
118
+ sizeof(ngx_udp_connection_t))
119
+ != NGX_OK)
120
+ {
121
+ return NULL;
122
+ }
123
+ }
124
+
113
125
  cln->data = r;
114
126
 
115
127
  r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
@@ -136,22 +148,47 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr)
136
148
 
137
149
  r->resend_timeout = 5;
138
150
  r->expire = 30;
139
- r->valid = 300;
151
+ r->valid = 0;
140
152
 
141
153
  r->log = &cf->cycle->new_log;
142
154
  r->log_level = NGX_LOG_ERR;
143
155
 
144
- if (addr) {
145
- uc = ngx_calloc(sizeof(ngx_udp_connection_t), cf->log);
156
+ for (i = 0; i < n; i++) {
157
+ if (ngx_strncmp(names[i].data, "valid=", 6) == 0) {
158
+ s.len = names[i].len - 6;
159
+ s.data = names[i].data + 6;
160
+
161
+ r->valid = ngx_parse_time(&s, 1);
162
+
163
+ if (r->valid == (time_t) NGX_ERROR) {
164
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
165
+ "invalid parameter: %V", &names[i]);
166
+ return NULL;
167
+ }
168
+
169
+ continue;
170
+ }
171
+
172
+ ngx_memzero(&u, sizeof(ngx_url_t));
173
+
174
+ u.host = names[i];
175
+ u.port = 53;
176
+
177
+ if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
178
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err);
179
+ return NULL;
180
+ }
181
+
182
+ uc = ngx_array_push(&r->udp_connections);
146
183
  if (uc == NULL) {
147
184
  return NULL;
148
185
  }
149
186
 
150
- r->udp_connection = uc;
187
+ ngx_memzero(uc, sizeof(ngx_udp_connection_t));
151
188
 
152
- uc->sockaddr = addr->sockaddr;
153
- uc->socklen = addr->socklen;
154
- uc->server = addr->name;
189
+ uc->sockaddr = u.addrs->sockaddr;
190
+ uc->socklen = u.addrs->socklen;
191
+ uc->server = u.addrs->name;
155
192
  }
156
193
 
157
194
  return r;
@@ -163,6 +200,9 @@ ngx_resolver_cleanup(void *data)
163
200
  {
164
201
  ngx_resolver_t *r = data;
165
202
 
203
+ ngx_uint_t i;
204
+ ngx_udp_connection_t *uc;
205
+
166
206
  if (r) {
167
207
  ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
168
208
  "cleanup resolver");
@@ -175,12 +215,13 @@ ngx_resolver_cleanup(void *data)
175
215
  ngx_free(r->event);
176
216
  }
177
217
 
178
- if (r->udp_connection) {
179
- if (r->udp_connection->connection) {
180
- ngx_close_connection(r->udp_connection->connection);
181
- }
182
218
 
183
- ngx_free(r->udp_connection);
219
+ uc = r->udp_connections.elts;
220
+
221
+ for (i = 0; i < r->udp_connections.nelts; i++) {
222
+ if (uc[i].connection) {
223
+ ngx_close_connection(uc[i].connection);
224
+ }
184
225
  }
185
226
 
186
227
  ngx_free(r);
@@ -238,7 +279,7 @@ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
238
279
  }
239
280
  }
240
281
 
241
- if (r->udp_connection == NULL) {
282
+ if (r->udp_connections.nelts == 0) {
242
283
  return NGX_NO_RESOLVER;
243
284
  }
244
285
 
@@ -822,7 +863,12 @@ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
822
863
  ssize_t n;
823
864
  ngx_udp_connection_t *uc;
824
865
 
825
- uc = r->udp_connection;
866
+ uc = r->udp_connections.elts;
867
+
868
+ uc = &uc[r->last_connection++];
869
+ if (r->last_connection == r->udp_connections.nelts) {
870
+ r->last_connection = 0;
871
+ }
826
872
 
827
873
  if (uc->connection == NULL) {
828
874
 
@@ -1121,6 +1167,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1121
1167
  char *err;
1122
1168
  u_char *cname;
1123
1169
  size_t len;
1170
+ int32_t ttl;
1124
1171
  uint32_t hash;
1125
1172
  in_addr_t addr, *addrs;
1126
1173
  ngx_str_t name;
@@ -1191,6 +1238,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1191
1238
  addrs = NULL;
1192
1239
  cname = NULL;
1193
1240
  qtype = 0;
1241
+ ttl = 0;
1194
1242
 
1195
1243
  for (a = 0; a < nan; a++) {
1196
1244
 
@@ -1230,6 +1278,12 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1230
1278
 
1231
1279
  qtype = (an->type_hi << 8) + an->type_lo;
1232
1280
  len = (an->len_hi << 8) + an->len_lo;
1281
+ ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
1282
+ + (an->ttl[2] << 8) + (an->ttl[3]);
1283
+
1284
+ if (ttl < 0) {
1285
+ ttl = 0;
1286
+ }
1233
1287
 
1234
1288
  if (qtype == NGX_RESOLVE_A) {
1235
1289
 
@@ -1259,8 +1313,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1259
1313
  }
1260
1314
  }
1261
1315
 
1262
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
1263
- "resolver naddrs:%ui cname:%p", naddrs, cname);
1316
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
1317
+ "resolver naddrs:%ui cname:%p ttl:%d",
1318
+ naddrs, cname, ttl);
1264
1319
 
1265
1320
  if (naddrs) {
1266
1321
 
@@ -1329,7 +1384,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1329
1384
 
1330
1385
  ngx_queue_remove(&rn->queue);
1331
1386
 
1332
- rn->valid = ngx_time() + r->valid;
1387
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
1333
1388
  rn->expire = ngx_time() + r->expire;
1334
1389
 
1335
1390
  ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
@@ -1371,7 +1426,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1371
1426
 
1372
1427
  rn->cnlen = (u_short) name.len;
1373
1428
  rn->u.cname = name.data;
1374
- rn->valid = ngx_time() + r->valid;
1429
+
1430
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
1375
1431
  rn->expire = ngx_time() + r->expire;
1376
1432
 
1377
1433
  ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
@@ -1422,6 +1478,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
1422
1478
  char *err;
1423
1479
  size_t len;
1424
1480
  in_addr_t addr;
1481
+ int32_t ttl;
1425
1482
  ngx_int_t digit;
1426
1483
  ngx_str_t name;
1427
1484
  ngx_uint_t i, mask, qident;
@@ -1517,6 +1574,12 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
1517
1574
  an = (ngx_resolver_an_t *) &buf[i + 2];
1518
1575
 
1519
1576
  len = (an->len_hi << 8) + an->len_lo;
1577
+ ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
1578
+ + (an->ttl[2] << 8) + (an->ttl[3]);
1579
+
1580
+ if (ttl < 0) {
1581
+ ttl = 0;
1582
+ }
1520
1583
 
1521
1584
  ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
1522
1585
  "resolver qt:%ui cl:%ui len:%uz",
@@ -1553,7 +1616,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
1553
1616
 
1554
1617
  ngx_queue_remove(&rn->queue);
1555
1618
 
1556
- rn->valid = ngx_time() + r->valid;
1619
+ rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
1557
1620
  rn->expire = ngx_time() + r->expire;
1558
1621
 
1559
1622
  ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
@@ -1777,7 +1840,7 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
1777
1840
  len++;
1778
1841
 
1779
1842
  } else {
1780
- if (len == 0) {
1843
+ if (len == 0 || len > 255) {
1781
1844
  return NGX_DECLINED;
1782
1845
  }
1783
1846
 
@@ -1788,6 +1851,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
1788
1851
  p--;
1789
1852
  }
1790
1853
 
1854
+ if (len == 0 || len > 255) {
1855
+ return NGX_DECLINED;
1856
+ }
1857
+
1791
1858
  *p = (u_char) len;
1792
1859
 
1793
1860
  return NGX_OK;