nginxtra 1.8.1.12 → 1.10.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +363 -25
  6. data/vendor/nginx/CHANGES.ru +365 -21
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/conf +32 -0
  9. data/vendor/nginx/auto/cc/gcc +1 -1
  10. data/vendor/nginx/auto/cc/icc +2 -2
  11. data/vendor/nginx/auto/cc/msvc +29 -8
  12. data/vendor/nginx/auto/cc/name +2 -25
  13. data/vendor/nginx/auto/cc/sunc +3 -0
  14. data/vendor/nginx/auto/endianness +7 -2
  15. data/vendor/nginx/auto/install +60 -26
  16. data/vendor/nginx/auto/lib/conf +4 -4
  17. data/vendor/nginx/auto/lib/geoip/conf +6 -1
  18. data/vendor/nginx/auto/lib/libgd/conf +6 -1
  19. data/vendor/nginx/auto/lib/libxslt/conf +11 -2
  20. data/vendor/nginx/auto/lib/make +1 -1
  21. data/vendor/nginx/auto/lib/md5/conf +2 -2
  22. data/vendor/nginx/auto/lib/md5/make +2 -2
  23. data/vendor/nginx/auto/lib/openssl/conf +52 -3
  24. data/vendor/nginx/auto/lib/openssl/make +1 -1
  25. data/vendor/nginx/auto/lib/pcre/conf +2 -2
  26. data/vendor/nginx/auto/lib/pcre/make +2 -2
  27. data/vendor/nginx/auto/lib/perl/conf +6 -3
  28. data/vendor/nginx/auto/lib/perl/make +4 -1
  29. data/vendor/nginx/auto/lib/sha1/conf +2 -2
  30. data/vendor/nginx/auto/lib/sha1/make +2 -2
  31. data/vendor/nginx/auto/lib/zlib/conf +2 -2
  32. data/vendor/nginx/auto/lib/zlib/make +2 -2
  33. data/vendor/nginx/auto/make +281 -16
  34. data/vendor/nginx/auto/module +122 -0
  35. data/vendor/nginx/auto/modules +909 -178
  36. data/vendor/nginx/auto/options +81 -19
  37. data/vendor/nginx/auto/os/conf +9 -0
  38. data/vendor/nginx/auto/os/darwin +3 -0
  39. data/vendor/nginx/auto/os/freebsd +0 -20
  40. data/vendor/nginx/auto/os/linux +0 -12
  41. data/vendor/nginx/auto/os/win32 +5 -1
  42. data/vendor/nginx/auto/sources +11 -311
  43. data/vendor/nginx/auto/summary +1 -0
  44. data/vendor/nginx/auto/types/sizeof +5 -3
  45. data/vendor/nginx/auto/types/typedef +9 -4
  46. data/vendor/nginx/auto/types/uintptr_t +7 -2
  47. data/vendor/nginx/auto/unix +72 -12
  48. data/vendor/nginx/conf/fastcgi.conf +1 -0
  49. data/vendor/nginx/conf/fastcgi_params +1 -0
  50. data/vendor/nginx/conf/scgi_params +1 -0
  51. data/vendor/nginx/conf/uwsgi_params +1 -0
  52. data/vendor/nginx/configure +1 -1
  53. data/vendor/nginx/contrib/vim/syntax/nginx.vim +2 -2
  54. data/vendor/nginx/man/nginx.8 +6 -2
  55. data/vendor/nginx/src/core/nginx.c +281 -114
  56. data/vendor/nginx/src/core/nginx.h +2 -2
  57. data/vendor/nginx/src/core/ngx_conf_file.c +54 -13
  58. data/vendor/nginx/src/core/ngx_conf_file.h +8 -52
  59. data/vendor/nginx/src/core/ngx_config.h +0 -5
  60. data/vendor/nginx/src/core/ngx_connection.c +270 -37
  61. data/vendor/nginx/src/core/ngx_connection.h +35 -12
  62. data/vendor/nginx/src/core/ngx_core.h +4 -0
  63. data/vendor/nginx/src/core/ngx_crypt.c +2 -2
  64. data/vendor/nginx/src/core/ngx_cycle.c +72 -25
  65. data/vendor/nginx/src/core/ngx_cycle.h +28 -39
  66. data/vendor/nginx/src/core/ngx_file.c +14 -5
  67. data/vendor/nginx/src/core/ngx_file.h +2 -0
  68. data/vendor/nginx/src/core/ngx_hash.c +13 -1
  69. data/vendor/nginx/src/core/ngx_inet.c +20 -18
  70. data/vendor/nginx/src/core/ngx_log.c +12 -12
  71. data/vendor/nginx/src/core/ngx_log.h +13 -6
  72. data/vendor/nginx/src/core/ngx_module.c +360 -0
  73. data/vendor/nginx/src/core/ngx_module.h +307 -0
  74. data/vendor/nginx/src/core/ngx_open_file_cache.c +2 -2
  75. data/vendor/nginx/src/core/ngx_output_chain.c +8 -4
  76. data/vendor/nginx/src/core/ngx_palloc.c +42 -44
  77. data/vendor/nginx/src/{http/ngx_http_parse_time.c → core/ngx_parse_time.c} +2 -3
  78. data/vendor/nginx/src/core/ngx_parse_time.h +22 -0
  79. data/vendor/nginx/src/core/ngx_proxy_protocol.c +50 -1
  80. data/vendor/nginx/src/core/ngx_proxy_protocol.h +3 -1
  81. data/vendor/nginx/src/core/ngx_regex.c +1 -38
  82. data/vendor/nginx/src/core/ngx_resolver.c +1814 -320
  83. data/vendor/nginx/src/core/ngx_resolver.h +67 -10
  84. data/vendor/nginx/src/core/ngx_rwlock.c +120 -0
  85. data/vendor/nginx/src/core/ngx_rwlock.h +21 -0
  86. data/vendor/nginx/src/core/ngx_slab.c +6 -5
  87. data/vendor/nginx/src/core/ngx_string.c +1 -1
  88. data/vendor/nginx/src/core/ngx_syslog.c +11 -3
  89. data/vendor/nginx/src/core/ngx_syslog.h +2 -1
  90. data/vendor/nginx/src/core/ngx_thread_pool.c +4 -0
  91. data/vendor/nginx/src/core/ngx_times.c +2 -2
  92. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +3 -1
  93. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +5 -2
  94. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +5 -5
  95. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +15 -8
  96. data/vendor/nginx/src/event/modules/ngx_poll_module.c +0 -10
  97. data/vendor/nginx/src/event/modules/ngx_select_module.c +0 -10
  98. data/vendor/nginx/src/event/ngx_event.c +60 -103
  99. data/vendor/nginx/src/event/ngx_event.h +22 -26
  100. data/vendor/nginx/src/event/ngx_event_accept.c +414 -88
  101. data/vendor/nginx/src/event/ngx_event_connect.c +27 -18
  102. data/vendor/nginx/src/event/ngx_event_connect.h +1 -0
  103. data/vendor/nginx/src/event/ngx_event_openssl.c +65 -25
  104. data/vendor/nginx/src/event/ngx_event_openssl.h +17 -0
  105. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +73 -7
  106. data/vendor/nginx/src/event/ngx_event_pipe.c +85 -27
  107. data/vendor/nginx/src/event/ngx_event_pipe.h +10 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_auth_request_module.c +2 -2
  110. data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +2 -2
  111. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +6 -6
  112. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +17 -11
  113. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +2 -2
  114. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +9 -9
  115. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +2 -2
  116. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +2 -2
  117. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +0 -7
  118. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +6 -6
  119. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +2 -1
  120. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +13 -13
  121. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +2 -2
  122. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +26 -21
  123. data/vendor/nginx/src/http/modules/ngx_http_random_index_module.c +1 -1
  124. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +26 -8
  125. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +73 -3
  126. data/vendor/nginx/src/http/modules/ngx_http_referer_module.c +1 -1
  127. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +6 -6
  128. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +5 -3
  129. data/vendor/nginx/src/http/modules/ngx_http_slice_filter_module.c +526 -0
  130. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +7 -7
  131. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +19 -16
  132. data/vendor/nginx/src/http/modules/ngx_http_static_module.c +1 -1
  133. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +1 -1
  134. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +373 -173
  135. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +72 -46
  136. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +18 -30
  137. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +50 -39
  138. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +38 -129
  139. data/vendor/nginx/src/http/modules/ngx_http_upstream_zone_module.c +246 -0
  140. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +6 -5
  141. data/vendor/nginx/src/http/modules/perl/nginx.xs +9 -9
  142. data/vendor/nginx/src/http/ngx_http.c +46 -43
  143. data/vendor/nginx/src/http/ngx_http.h +4 -9
  144. data/vendor/nginx/src/http/ngx_http_cache.h +4 -0
  145. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +13 -5
  146. data/vendor/nginx/src/http/ngx_http_core_module.c +92 -91
  147. data/vendor/nginx/src/http/ngx_http_core_module.h +12 -8
  148. data/vendor/nginx/src/http/ngx_http_file_cache.c +61 -10
  149. data/vendor/nginx/src/http/ngx_http_request.c +37 -50
  150. data/vendor/nginx/src/http/ngx_http_request.h +10 -15
  151. data/vendor/nginx/src/http/ngx_http_request_body.c +64 -88
  152. data/vendor/nginx/src/http/ngx_http_script.c +3 -3
  153. data/vendor/nginx/src/http/ngx_http_special_response.c +1 -4
  154. data/vendor/nginx/src/http/ngx_http_upstream.c +245 -109
  155. data/vendor/nginx/src/http/ngx_http_upstream.h +11 -5
  156. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +212 -65
  157. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +66 -5
  158. data/vendor/nginx/src/http/ngx_http_variables.c +28 -15
  159. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +1 -1
  160. data/vendor/nginx/src/http/v2/ngx_http_v2.c +4349 -0
  161. data/vendor/nginx/src/http/v2/ngx_http_v2.h +337 -0
  162. data/vendor/nginx/src/http/v2/ngx_http_v2_filter_module.c +1391 -0
  163. data/vendor/nginx/src/http/v2/ngx_http_v2_huff_decode.c +2714 -0
  164. data/vendor/nginx/src/http/v2/ngx_http_v2_huff_encode.c +254 -0
  165. data/vendor/nginx/src/http/v2/ngx_http_v2_module.c +469 -0
  166. data/vendor/nginx/src/http/{ngx_http_spdy_module.h → v2/ngx_http_v2_module.h} +10 -9
  167. data/vendor/nginx/src/http/v2/ngx_http_v2_table.c +349 -0
  168. data/vendor/nginx/src/mail/ngx_mail.c +49 -82
  169. data/vendor/nginx/src/mail/ngx_mail.h +16 -23
  170. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +1 -1
  171. data/vendor/nginx/src/mail/ngx_mail_core_module.c +60 -34
  172. data/vendor/nginx/src/mail/ngx_mail_handler.c +17 -12
  173. data/vendor/nginx/src/mail/ngx_mail_proxy_module.c +1 -14
  174. data/vendor/nginx/src/mail/ngx_mail_smtp_handler.c +1 -1
  175. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +5 -5
  176. data/vendor/nginx/src/os/unix/ngx_atomic.h +10 -10
  177. data/vendor/nginx/src/os/unix/ngx_channel.h +4 -4
  178. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +2 -0
  179. data/vendor/nginx/src/os/unix/ngx_darwin_init.c +1 -0
  180. data/vendor/nginx/src/os/unix/ngx_dlopen.c +28 -0
  181. data/vendor/nginx/src/os/unix/ngx_dlopen.h +31 -0
  182. data/vendor/nginx/src/os/unix/ngx_errno.h +1 -0
  183. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +1 -1
  184. data/vendor/nginx/src/os/unix/ngx_files.c +313 -80
  185. data/vendor/nginx/src/os/unix/ngx_files.h +5 -2
  186. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +3 -1
  187. data/vendor/nginx/src/os/unix/ngx_freebsd_init.c +1 -0
  188. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +13 -0
  189. data/vendor/nginx/src/os/unix/ngx_linux.h +0 -2
  190. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +1 -1
  191. data/vendor/nginx/src/os/unix/ngx_linux_config.h +2 -6
  192. data/vendor/nginx/src/os/unix/ngx_linux_init.c +1 -33
  193. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +55 -12
  194. data/vendor/nginx/src/os/unix/ngx_os.h +3 -9
  195. data/vendor/nginx/src/os/unix/ngx_posix_config.h +14 -1
  196. data/vendor/nginx/src/os/unix/ngx_posix_init.c +2 -1
  197. data/vendor/nginx/src/os/unix/ngx_process.c +1 -1
  198. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +25 -51
  199. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +1 -0
  200. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +24 -28
  201. data/vendor/nginx/src/os/unix/ngx_recv.c +30 -79
  202. data/vendor/nginx/src/os/unix/ngx_send.c +1 -1
  203. data/vendor/nginx/src/os/unix/ngx_setaffinity.c +14 -30
  204. data/vendor/nginx/src/os/unix/ngx_setaffinity.h +15 -1
  205. data/vendor/nginx/src/os/unix/ngx_solaris_config.h +2 -0
  206. data/vendor/nginx/src/os/unix/ngx_solaris_init.c +1 -0
  207. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +23 -0
  208. data/vendor/nginx/src/os/unix/ngx_sunpro_amd64.il +3 -3
  209. data/vendor/nginx/src/os/unix/ngx_sunpro_x86.il +3 -3
  210. data/vendor/nginx/src/os/unix/ngx_udp_recv.c +5 -48
  211. data/vendor/nginx/src/os/unix/ngx_udp_send.c +56 -0
  212. data/vendor/nginx/src/stream/ngx_stream.c +564 -0
  213. data/vendor/nginx/src/stream/ngx_stream.h +212 -0
  214. data/vendor/nginx/src/stream/ngx_stream_access_module.c +451 -0
  215. data/vendor/nginx/src/stream/ngx_stream_core_module.c +562 -0
  216. data/vendor/nginx/src/stream/ngx_stream_handler.c +344 -0
  217. data/vendor/nginx/src/stream/ngx_stream_limit_conn_module.c +632 -0
  218. data/vendor/nginx/src/stream/ngx_stream_proxy_module.c +1674 -0
  219. data/vendor/nginx/src/stream/ngx_stream_ssl_module.c +460 -0
  220. data/vendor/nginx/src/stream/ngx_stream_ssl_module.h +49 -0
  221. data/vendor/nginx/src/stream/ngx_stream_upstream.c +464 -0
  222. data/vendor/nginx/src/stream/ngx_stream_upstream.h +107 -0
  223. data/vendor/nginx/src/stream/ngx_stream_upstream_hash_module.c +656 -0
  224. data/vendor/nginx/src/stream/ngx_stream_upstream_least_conn_module.c +307 -0
  225. data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.c +702 -0
  226. data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.h +139 -0
  227. data/vendor/nginx/src/stream/ngx_stream_upstream_zone_module.c +242 -0
  228. metadata +39 -15
  229. data/vendor/nginx/src/event/modules/ngx_aio_module.c +0 -171
  230. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +0 -735
  231. data/vendor/nginx/src/http/ngx_http_spdy.c +0 -3701
  232. data/vendor/nginx/src/http/ngx_http_spdy.h +0 -261
  233. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +0 -1222
  234. data/vendor/nginx/src/http/ngx_http_spdy_module.c +0 -408
  235. data/vendor/nginx/src/os/unix/ngx_aio_read.c +0 -109
  236. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +0 -78
  237. data/vendor/nginx/src/os/unix/ngx_aio_write.c +0 -109
  238. data/vendor/nginx/src/os/unix/ngx_aio_write_chain.c +0 -100
@@ -0,0 +1,107 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #ifndef _NGX_STREAM_UPSTREAM_H_INCLUDED_
9
+ #define _NGX_STREAM_UPSTREAM_H_INCLUDED_
10
+
11
+
12
+ #include <ngx_config.h>
13
+ #include <ngx_core.h>
14
+ #include <ngx_stream.h>
15
+ #include <ngx_event_connect.h>
16
+
17
+
18
+ #define NGX_STREAM_UPSTREAM_CREATE 0x0001
19
+ #define NGX_STREAM_UPSTREAM_WEIGHT 0x0002
20
+ #define NGX_STREAM_UPSTREAM_MAX_FAILS 0x0004
21
+ #define NGX_STREAM_UPSTREAM_FAIL_TIMEOUT 0x0008
22
+ #define NGX_STREAM_UPSTREAM_DOWN 0x0010
23
+ #define NGX_STREAM_UPSTREAM_BACKUP 0x0020
24
+
25
+
26
+ typedef struct {
27
+ ngx_array_t upstreams;
28
+ /* ngx_stream_upstream_srv_conf_t */
29
+ } ngx_stream_upstream_main_conf_t;
30
+
31
+
32
+ typedef struct ngx_stream_upstream_srv_conf_s ngx_stream_upstream_srv_conf_t;
33
+
34
+
35
+ typedef ngx_int_t (*ngx_stream_upstream_init_pt)(ngx_conf_t *cf,
36
+ ngx_stream_upstream_srv_conf_t *us);
37
+ typedef ngx_int_t (*ngx_stream_upstream_init_peer_pt)(ngx_stream_session_t *s,
38
+ ngx_stream_upstream_srv_conf_t *us);
39
+
40
+
41
+ typedef struct {
42
+ ngx_stream_upstream_init_pt init_upstream;
43
+ ngx_stream_upstream_init_peer_pt init;
44
+ void *data;
45
+ } ngx_stream_upstream_peer_t;
46
+
47
+
48
+ typedef struct {
49
+ ngx_str_t name;
50
+ ngx_addr_t *addrs;
51
+ ngx_uint_t naddrs;
52
+ ngx_uint_t weight;
53
+ ngx_uint_t max_fails;
54
+ time_t fail_timeout;
55
+
56
+ unsigned down:1;
57
+ unsigned backup:1;
58
+ } ngx_stream_upstream_server_t;
59
+
60
+
61
+ struct ngx_stream_upstream_srv_conf_s {
62
+ ngx_stream_upstream_peer_t peer;
63
+ void **srv_conf;
64
+
65
+ ngx_array_t *servers;
66
+ /* ngx_stream_upstream_server_t */
67
+
68
+ ngx_uint_t flags;
69
+ ngx_str_t host;
70
+ u_char *file_name;
71
+ ngx_uint_t line;
72
+ in_port_t port;
73
+ ngx_uint_t no_port; /* unsigned no_port:1 */
74
+
75
+ #if (NGX_STREAM_UPSTREAM_ZONE)
76
+ ngx_shm_zone_t *shm_zone;
77
+ #endif
78
+ };
79
+
80
+
81
+ typedef struct {
82
+ ngx_peer_connection_t peer;
83
+ ngx_buf_t downstream_buf;
84
+ ngx_buf_t upstream_buf;
85
+ off_t received;
86
+ time_t start_sec;
87
+ ngx_uint_t responses;
88
+ #if (NGX_STREAM_SSL)
89
+ ngx_str_t ssl_name;
90
+ #endif
91
+ unsigned connected:1;
92
+ unsigned proxy_protocol:1;
93
+ } ngx_stream_upstream_t;
94
+
95
+
96
+ ngx_stream_upstream_srv_conf_t *ngx_stream_upstream_add(ngx_conf_t *cf,
97
+ ngx_url_t *u, ngx_uint_t flags);
98
+
99
+
100
+ #define ngx_stream_conf_upstream_srv_conf(uscf, module) \
101
+ uscf->srv_conf[module.ctx_index]
102
+
103
+
104
+ extern ngx_module_t ngx_stream_upstream_module;
105
+
106
+
107
+ #endif /* _NGX_STREAM_UPSTREAM_H_INCLUDED_ */
@@ -0,0 +1,656 @@
1
+
2
+ /*
3
+ * Copyright (C) Roman Arutyunyan
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #include <ngx_config.h>
9
+ #include <ngx_core.h>
10
+ #include <ngx_stream.h>
11
+
12
+
13
+ typedef struct {
14
+ uint32_t hash;
15
+ ngx_str_t *server;
16
+ } ngx_stream_upstream_chash_point_t;
17
+
18
+
19
+ typedef struct {
20
+ ngx_uint_t number;
21
+ ngx_stream_upstream_chash_point_t point[1];
22
+ } ngx_stream_upstream_chash_points_t;
23
+
24
+
25
+ typedef struct {
26
+ ngx_stream_upstream_chash_points_t *points;
27
+ } ngx_stream_upstream_hash_srv_conf_t;
28
+
29
+
30
+ typedef struct {
31
+ /* the round robin data must be first */
32
+ ngx_stream_upstream_rr_peer_data_t rrp;
33
+ ngx_stream_upstream_hash_srv_conf_t *conf;
34
+ ngx_str_t key;
35
+ ngx_uint_t tries;
36
+ ngx_uint_t rehash;
37
+ uint32_t hash;
38
+ ngx_event_get_peer_pt get_rr_peer;
39
+ } ngx_stream_upstream_hash_peer_data_t;
40
+
41
+
42
+ static ngx_int_t ngx_stream_upstream_init_hash(ngx_conf_t *cf,
43
+ ngx_stream_upstream_srv_conf_t *us);
44
+ static ngx_int_t ngx_stream_upstream_init_hash_peer(ngx_stream_session_t *s,
45
+ ngx_stream_upstream_srv_conf_t *us);
46
+ static ngx_int_t ngx_stream_upstream_get_hash_peer(ngx_peer_connection_t *pc,
47
+ void *data);
48
+
49
+ static ngx_int_t ngx_stream_upstream_init_chash(ngx_conf_t *cf,
50
+ ngx_stream_upstream_srv_conf_t *us);
51
+ static int ngx_libc_cdecl
52
+ ngx_stream_upstream_chash_cmp_points(const void *one, const void *two);
53
+ static ngx_uint_t ngx_stream_upstream_find_chash_point(
54
+ ngx_stream_upstream_chash_points_t *points, uint32_t hash);
55
+ static ngx_int_t ngx_stream_upstream_init_chash_peer(ngx_stream_session_t *s,
56
+ ngx_stream_upstream_srv_conf_t *us);
57
+ static ngx_int_t ngx_stream_upstream_get_chash_peer(ngx_peer_connection_t *pc,
58
+ void *data);
59
+
60
+ static void *ngx_stream_upstream_hash_create_conf(ngx_conf_t *cf);
61
+ static char *ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd,
62
+ void *conf);
63
+
64
+
65
+ static ngx_command_t ngx_stream_upstream_hash_commands[] = {
66
+
67
+ { ngx_string("hash"),
68
+ NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12,
69
+ ngx_stream_upstream_hash,
70
+ NGX_STREAM_SRV_CONF_OFFSET,
71
+ 0,
72
+ NULL },
73
+
74
+ ngx_null_command
75
+ };
76
+
77
+
78
+ static ngx_stream_module_t ngx_stream_upstream_hash_module_ctx = {
79
+ NULL, /* postconfiguration */
80
+
81
+ NULL, /* create main configuration */
82
+ NULL, /* init main configuration */
83
+
84
+ ngx_stream_upstream_hash_create_conf, /* create server configuration */
85
+ NULL, /* merge server configuration */
86
+ };
87
+
88
+
89
+ ngx_module_t ngx_stream_upstream_hash_module = {
90
+ NGX_MODULE_V1,
91
+ &ngx_stream_upstream_hash_module_ctx, /* module context */
92
+ ngx_stream_upstream_hash_commands, /* module directives */
93
+ NGX_STREAM_MODULE, /* module type */
94
+ NULL, /* init master */
95
+ NULL, /* init module */
96
+ NULL, /* init process */
97
+ NULL, /* init thread */
98
+ NULL, /* exit thread */
99
+ NULL, /* exit process */
100
+ NULL, /* exit master */
101
+ NGX_MODULE_V1_PADDING
102
+ };
103
+
104
+
105
+ static ngx_int_t
106
+ ngx_stream_upstream_init_hash(ngx_conf_t *cf,
107
+ ngx_stream_upstream_srv_conf_t *us)
108
+ {
109
+ if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) {
110
+ return NGX_ERROR;
111
+ }
112
+
113
+ us->peer.init = ngx_stream_upstream_init_hash_peer;
114
+
115
+ return NGX_OK;
116
+ }
117
+
118
+
119
+ static ngx_int_t
120
+ ngx_stream_upstream_init_hash_peer(ngx_stream_session_t *s,
121
+ ngx_stream_upstream_srv_conf_t *us)
122
+ {
123
+ ngx_stream_upstream_hash_srv_conf_t *hcf;
124
+ ngx_stream_upstream_hash_peer_data_t *hp;
125
+
126
+ hp = ngx_palloc(s->connection->pool,
127
+ sizeof(ngx_stream_upstream_hash_peer_data_t));
128
+ if (hp == NULL) {
129
+ return NGX_ERROR;
130
+ }
131
+
132
+ s->upstream->peer.data = &hp->rrp;
133
+
134
+ if (ngx_stream_upstream_init_round_robin_peer(s, us) != NGX_OK) {
135
+ return NGX_ERROR;
136
+ }
137
+
138
+ s->upstream->peer.get = ngx_stream_upstream_get_hash_peer;
139
+
140
+ hcf = ngx_stream_conf_upstream_srv_conf(us,
141
+ ngx_stream_upstream_hash_module);
142
+
143
+ hp->key = s->connection->addr_text;
144
+
145
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
146
+ "upstream hash key:\"%V\"", &hp->key);
147
+
148
+ hp->conf = hcf;
149
+ hp->tries = 0;
150
+ hp->rehash = 0;
151
+ hp->hash = 0;
152
+ hp->get_rr_peer = ngx_stream_upstream_get_round_robin_peer;
153
+
154
+ return NGX_OK;
155
+ }
156
+
157
+
158
+ static ngx_int_t
159
+ ngx_stream_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data)
160
+ {
161
+ ngx_stream_upstream_hash_peer_data_t *hp = data;
162
+
163
+ time_t now;
164
+ u_char buf[NGX_INT_T_LEN];
165
+ size_t size;
166
+ uint32_t hash;
167
+ ngx_int_t w;
168
+ uintptr_t m;
169
+ ngx_uint_t n, p;
170
+ ngx_stream_upstream_rr_peer_t *peer;
171
+
172
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
173
+ "get hash peer, try: %ui", pc->tries);
174
+
175
+ ngx_stream_upstream_rr_peers_wlock(hp->rrp.peers);
176
+
177
+ if (hp->tries > 20 || hp->rrp.peers->single) {
178
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
179
+ return hp->get_rr_peer(pc, &hp->rrp);
180
+ }
181
+
182
+ now = ngx_time();
183
+
184
+ pc->connection = NULL;
185
+
186
+ for ( ;; ) {
187
+
188
+ /*
189
+ * Hash expression is compatible with Cache::Memcached:
190
+ * ((crc32([REHASH] KEY) >> 16) & 0x7fff) + PREV_HASH
191
+ * with REHASH omitted at the first iteration.
192
+ */
193
+
194
+ ngx_crc32_init(hash);
195
+
196
+ if (hp->rehash > 0) {
197
+ size = ngx_sprintf(buf, "%ui", hp->rehash) - buf;
198
+ ngx_crc32_update(&hash, buf, size);
199
+ }
200
+
201
+ ngx_crc32_update(&hash, hp->key.data, hp->key.len);
202
+ ngx_crc32_final(hash);
203
+
204
+ hash = (hash >> 16) & 0x7fff;
205
+
206
+ hp->hash += hash;
207
+ hp->rehash++;
208
+
209
+ w = hp->hash % hp->rrp.peers->total_weight;
210
+ peer = hp->rrp.peers->peer;
211
+ p = 0;
212
+
213
+ while (w >= peer->weight) {
214
+ w -= peer->weight;
215
+ peer = peer->next;
216
+ p++;
217
+ }
218
+
219
+ n = p / (8 * sizeof(uintptr_t));
220
+ m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
221
+
222
+ if (hp->rrp.tried[n] & m) {
223
+ goto next;
224
+ }
225
+
226
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0,
227
+ "get hash peer, value:%uD, peer:%ui", hp->hash, p);
228
+
229
+ if (peer->down) {
230
+ goto next;
231
+ }
232
+
233
+ if (peer->max_fails
234
+ && peer->fails >= peer->max_fails
235
+ && now - peer->checked <= peer->fail_timeout)
236
+ {
237
+ goto next;
238
+ }
239
+
240
+ break;
241
+
242
+ next:
243
+
244
+ if (++hp->tries > 20) {
245
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
246
+ return hp->get_rr_peer(pc, &hp->rrp);
247
+ }
248
+ }
249
+
250
+ hp->rrp.current = peer;
251
+
252
+ pc->sockaddr = peer->sockaddr;
253
+ pc->socklen = peer->socklen;
254
+ pc->name = &peer->name;
255
+
256
+ peer->conns++;
257
+
258
+ if (now - peer->checked > peer->fail_timeout) {
259
+ peer->checked = now;
260
+ }
261
+
262
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
263
+
264
+ hp->rrp.tried[n] |= m;
265
+
266
+ return NGX_OK;
267
+ }
268
+
269
+
270
+ static ngx_int_t
271
+ ngx_stream_upstream_init_chash(ngx_conf_t *cf,
272
+ ngx_stream_upstream_srv_conf_t *us)
273
+ {
274
+ u_char *host, *port, c;
275
+ size_t host_len, port_len, size;
276
+ uint32_t hash, base_hash;
277
+ ngx_str_t *server;
278
+ ngx_uint_t npoints, i, j;
279
+ ngx_stream_upstream_rr_peer_t *peer;
280
+ ngx_stream_upstream_rr_peers_t *peers;
281
+ ngx_stream_upstream_chash_points_t *points;
282
+ ngx_stream_upstream_hash_srv_conf_t *hcf;
283
+ union {
284
+ uint32_t value;
285
+ u_char byte[4];
286
+ } prev_hash;
287
+
288
+ if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) {
289
+ return NGX_ERROR;
290
+ }
291
+
292
+ us->peer.init = ngx_stream_upstream_init_chash_peer;
293
+
294
+ peers = us->peer.data;
295
+ npoints = peers->total_weight * 160;
296
+
297
+ size = sizeof(ngx_stream_upstream_chash_points_t)
298
+ + sizeof(ngx_stream_upstream_chash_point_t) * (npoints - 1);
299
+
300
+ points = ngx_palloc(cf->pool, size);
301
+ if (points == NULL) {
302
+ return NGX_ERROR;
303
+ }
304
+
305
+ points->number = 0;
306
+
307
+ for (peer = peers->peer; peer; peer = peer->next) {
308
+ server = &peer->server;
309
+
310
+ /*
311
+ * Hash expression is compatible with Cache::Memcached::Fast:
312
+ * crc32(HOST \0 PORT PREV_HASH).
313
+ */
314
+
315
+ if (server->len >= 5
316
+ && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0)
317
+ {
318
+ host = server->data + 5;
319
+ host_len = server->len - 5;
320
+ port = NULL;
321
+ port_len = 0;
322
+ goto done;
323
+ }
324
+
325
+ for (j = 0; j < server->len; j++) {
326
+ c = server->data[server->len - j - 1];
327
+
328
+ if (c == ':') {
329
+ host = server->data;
330
+ host_len = server->len - j - 1;
331
+ port = server->data + server->len - j;
332
+ port_len = j;
333
+ goto done;
334
+ }
335
+
336
+ if (c < '0' || c > '9') {
337
+ break;
338
+ }
339
+ }
340
+
341
+ host = server->data;
342
+ host_len = server->len;
343
+ port = NULL;
344
+ port_len = 0;
345
+
346
+ done:
347
+
348
+ ngx_crc32_init(base_hash);
349
+ ngx_crc32_update(&base_hash, host, host_len);
350
+ ngx_crc32_update(&base_hash, (u_char *) "", 1);
351
+ ngx_crc32_update(&base_hash, port, port_len);
352
+
353
+ prev_hash.value = 0;
354
+ npoints = peer->weight * 160;
355
+
356
+ for (j = 0; j < npoints; j++) {
357
+ hash = base_hash;
358
+
359
+ ngx_crc32_update(&hash, prev_hash.byte, 4);
360
+ ngx_crc32_final(hash);
361
+
362
+ points->point[points->number].hash = hash;
363
+ points->point[points->number].server = server;
364
+ points->number++;
365
+
366
+ #if (NGX_HAVE_LITTLE_ENDIAN)
367
+ prev_hash.value = hash;
368
+ #else
369
+ prev_hash.byte[0] = (u_char) (hash & 0xff);
370
+ prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff);
371
+ prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff);
372
+ prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff);
373
+ #endif
374
+ }
375
+ }
376
+
377
+ ngx_qsort(points->point,
378
+ points->number,
379
+ sizeof(ngx_stream_upstream_chash_point_t),
380
+ ngx_stream_upstream_chash_cmp_points);
381
+
382
+ for (i = 0, j = 1; j < points->number; j++) {
383
+ if (points->point[i].hash != points->point[j].hash) {
384
+ points->point[++i] = points->point[j];
385
+ }
386
+ }
387
+
388
+ points->number = i + 1;
389
+
390
+ hcf = ngx_stream_conf_upstream_srv_conf(us,
391
+ ngx_stream_upstream_hash_module);
392
+ hcf->points = points;
393
+
394
+ return NGX_OK;
395
+ }
396
+
397
+
398
+ static int ngx_libc_cdecl
399
+ ngx_stream_upstream_chash_cmp_points(const void *one, const void *two)
400
+ {
401
+ ngx_stream_upstream_chash_point_t *first =
402
+ (ngx_stream_upstream_chash_point_t *) one;
403
+ ngx_stream_upstream_chash_point_t *second =
404
+ (ngx_stream_upstream_chash_point_t *) two;
405
+
406
+ if (first->hash < second->hash) {
407
+ return -1;
408
+
409
+ } else if (first->hash > second->hash) {
410
+ return 1;
411
+
412
+ } else {
413
+ return 0;
414
+ }
415
+ }
416
+
417
+
418
+ static ngx_uint_t
419
+ ngx_stream_upstream_find_chash_point(ngx_stream_upstream_chash_points_t *points,
420
+ uint32_t hash)
421
+ {
422
+ ngx_uint_t i, j, k;
423
+ ngx_stream_upstream_chash_point_t *point;
424
+
425
+ /* find first point >= hash */
426
+
427
+ point = &points->point[0];
428
+
429
+ i = 0;
430
+ j = points->number;
431
+
432
+ while (i < j) {
433
+ k = (i + j) / 2;
434
+
435
+ if (hash > point[k].hash) {
436
+ i = k + 1;
437
+
438
+ } else if (hash < point[k].hash) {
439
+ j = k;
440
+
441
+ } else {
442
+ return k;
443
+ }
444
+ }
445
+
446
+ return i;
447
+ }
448
+
449
+
450
+ static ngx_int_t
451
+ ngx_stream_upstream_init_chash_peer(ngx_stream_session_t *s,
452
+ ngx_stream_upstream_srv_conf_t *us)
453
+ {
454
+ uint32_t hash;
455
+ ngx_stream_upstream_hash_srv_conf_t *hcf;
456
+ ngx_stream_upstream_hash_peer_data_t *hp;
457
+
458
+ if (ngx_stream_upstream_init_hash_peer(s, us) != NGX_OK) {
459
+ return NGX_ERROR;
460
+ }
461
+
462
+ s->upstream->peer.get = ngx_stream_upstream_get_chash_peer;
463
+
464
+ hp = s->upstream->peer.data;
465
+ hcf = ngx_stream_conf_upstream_srv_conf(us,
466
+ ngx_stream_upstream_hash_module);
467
+
468
+ hash = ngx_crc32_long(hp->key.data, hp->key.len);
469
+
470
+ ngx_stream_upstream_rr_peers_rlock(hp->rrp.peers);
471
+
472
+ hp->hash = ngx_stream_upstream_find_chash_point(hcf->points, hash);
473
+
474
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
475
+
476
+ return NGX_OK;
477
+ }
478
+
479
+
480
+ static ngx_int_t
481
+ ngx_stream_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data)
482
+ {
483
+ ngx_stream_upstream_hash_peer_data_t *hp = data;
484
+
485
+ time_t now;
486
+ intptr_t m;
487
+ ngx_str_t *server;
488
+ ngx_int_t total;
489
+ ngx_uint_t i, n, best_i;
490
+ ngx_stream_upstream_rr_peer_t *peer, *best;
491
+ ngx_stream_upstream_chash_point_t *point;
492
+ ngx_stream_upstream_chash_points_t *points;
493
+ ngx_stream_upstream_hash_srv_conf_t *hcf;
494
+
495
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
496
+ "get consistent hash peer, try: %ui", pc->tries);
497
+
498
+ ngx_stream_upstream_rr_peers_wlock(hp->rrp.peers);
499
+
500
+ pc->connection = NULL;
501
+
502
+ now = ngx_time();
503
+ hcf = hp->conf;
504
+
505
+ points = hcf->points;
506
+ point = &points->point[0];
507
+
508
+ for ( ;; ) {
509
+ server = point[hp->hash % points->number].server;
510
+
511
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0,
512
+ "consistent hash peer:%uD, server:\"%V\"",
513
+ hp->hash, server);
514
+
515
+ best = NULL;
516
+ best_i = 0;
517
+ total = 0;
518
+
519
+ for (peer = hp->rrp.peers->peer, i = 0;
520
+ peer;
521
+ peer = peer->next, i++)
522
+ {
523
+
524
+ n = i / (8 * sizeof(uintptr_t));
525
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
526
+
527
+ if (hp->rrp.tried[n] & m) {
528
+ continue;
529
+ }
530
+
531
+ if (peer->down) {
532
+ continue;
533
+ }
534
+
535
+ if (peer->server.len != server->len
536
+ || ngx_strncmp(peer->server.data, server->data, server->len)
537
+ != 0)
538
+ {
539
+ continue;
540
+ }
541
+
542
+ if (peer->max_fails
543
+ && peer->fails >= peer->max_fails
544
+ && now - peer->checked <= peer->fail_timeout)
545
+ {
546
+ continue;
547
+ }
548
+
549
+ peer->current_weight += peer->effective_weight;
550
+ total += peer->effective_weight;
551
+
552
+ if (peer->effective_weight < peer->weight) {
553
+ peer->effective_weight++;
554
+ }
555
+
556
+ if (best == NULL || peer->current_weight > best->current_weight) {
557
+ best = peer;
558
+ best_i = i;
559
+ }
560
+ }
561
+
562
+ if (best) {
563
+ best->current_weight -= total;
564
+ break;
565
+ }
566
+
567
+ hp->hash++;
568
+ hp->tries++;
569
+
570
+ if (hp->tries >= points->number) {
571
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
572
+ return NGX_BUSY;
573
+ }
574
+ }
575
+
576
+ hp->rrp.current = best;
577
+
578
+ pc->sockaddr = best->sockaddr;
579
+ pc->socklen = best->socklen;
580
+ pc->name = &best->name;
581
+
582
+ best->conns++;
583
+
584
+ if (now - best->checked > best->fail_timeout) {
585
+ best->checked = now;
586
+ }
587
+
588
+ ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
589
+
590
+ n = best_i / (8 * sizeof(uintptr_t));
591
+ m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t));
592
+
593
+ hp->rrp.tried[n] |= m;
594
+
595
+ return NGX_OK;
596
+ }
597
+
598
+
599
+ static void *
600
+ ngx_stream_upstream_hash_create_conf(ngx_conf_t *cf)
601
+ {
602
+ ngx_stream_upstream_hash_srv_conf_t *conf;
603
+
604
+ conf = ngx_palloc(cf->pool, sizeof(ngx_stream_upstream_hash_srv_conf_t));
605
+ if (conf == NULL) {
606
+ return NULL;
607
+ }
608
+
609
+ conf->points = NULL;
610
+
611
+ return conf;
612
+ }
613
+
614
+
615
+ static char *
616
+ ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
617
+ {
618
+ ngx_str_t *value;
619
+ ngx_stream_upstream_srv_conf_t *uscf;
620
+
621
+ value = cf->args->elts;
622
+
623
+ if (ngx_strcmp(value[1].data, "$remote_addr")) {
624
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
625
+ "unsupported hash key \"%V\", use $remote_addr",
626
+ &value[1]);
627
+ return NGX_CONF_ERROR;
628
+ }
629
+
630
+ uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module);
631
+
632
+ if (uscf->peer.init_upstream) {
633
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
634
+ "load balancing method redefined");
635
+ }
636
+
637
+ uscf->flags = NGX_STREAM_UPSTREAM_CREATE
638
+ |NGX_STREAM_UPSTREAM_WEIGHT
639
+ |NGX_STREAM_UPSTREAM_MAX_FAILS
640
+ |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
641
+ |NGX_STREAM_UPSTREAM_DOWN;
642
+
643
+ if (cf->args->nelts == 2) {
644
+ uscf->peer.init_upstream = ngx_stream_upstream_init_hash;
645
+
646
+ } else if (ngx_strcmp(value[2].data, "consistent") == 0) {
647
+ uscf->peer.init_upstream = ngx_stream_upstream_init_chash;
648
+
649
+ } else {
650
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
651
+ "invalid parameter \"%V\"", &value[2]);
652
+ return NGX_CONF_ERROR;
653
+ }
654
+
655
+ return NGX_CONF_OK;
656
+ }