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,307 @@
1
+
2
+ /*
3
+ * Copyright (C) Maxim Dounin
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
+ static ngx_int_t ngx_stream_upstream_init_least_conn_peer(
14
+ ngx_stream_session_t *s, ngx_stream_upstream_srv_conf_t *us);
15
+ static ngx_int_t ngx_stream_upstream_get_least_conn_peer(
16
+ ngx_peer_connection_t *pc, void *data);
17
+ static char *ngx_stream_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd,
18
+ void *conf);
19
+
20
+
21
+ static ngx_command_t ngx_stream_upstream_least_conn_commands[] = {
22
+
23
+ { ngx_string("least_conn"),
24
+ NGX_STREAM_UPS_CONF|NGX_CONF_NOARGS,
25
+ ngx_stream_upstream_least_conn,
26
+ 0,
27
+ 0,
28
+ NULL },
29
+
30
+ ngx_null_command
31
+ };
32
+
33
+
34
+ static ngx_stream_module_t ngx_stream_upstream_least_conn_module_ctx = {
35
+ NULL, /* postconfiguration */
36
+
37
+ NULL, /* create main configuration */
38
+ NULL, /* init main configuration */
39
+
40
+ NULL, /* create server configuration */
41
+ NULL, /* merge server configuration */
42
+ };
43
+
44
+
45
+ ngx_module_t ngx_stream_upstream_least_conn_module = {
46
+ NGX_MODULE_V1,
47
+ &ngx_stream_upstream_least_conn_module_ctx, /* module context */
48
+ ngx_stream_upstream_least_conn_commands, /* module directives */
49
+ NGX_STREAM_MODULE, /* module type */
50
+ NULL, /* init master */
51
+ NULL, /* init module */
52
+ NULL, /* init process */
53
+ NULL, /* init thread */
54
+ NULL, /* exit thread */
55
+ NULL, /* exit process */
56
+ NULL, /* exit master */
57
+ NGX_MODULE_V1_PADDING
58
+ };
59
+
60
+
61
+ static ngx_int_t
62
+ ngx_stream_upstream_init_least_conn(ngx_conf_t *cf,
63
+ ngx_stream_upstream_srv_conf_t *us)
64
+ {
65
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, cf->log, 0,
66
+ "init least conn");
67
+
68
+ if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) {
69
+ return NGX_ERROR;
70
+ }
71
+
72
+ us->peer.init = ngx_stream_upstream_init_least_conn_peer;
73
+
74
+ return NGX_OK;
75
+ }
76
+
77
+
78
+ static ngx_int_t
79
+ ngx_stream_upstream_init_least_conn_peer(ngx_stream_session_t *s,
80
+ ngx_stream_upstream_srv_conf_t *us)
81
+ {
82
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
83
+ "init least conn peer");
84
+
85
+ if (ngx_stream_upstream_init_round_robin_peer(s, us) != NGX_OK) {
86
+ return NGX_ERROR;
87
+ }
88
+
89
+ s->upstream->peer.get = ngx_stream_upstream_get_least_conn_peer;
90
+
91
+ return NGX_OK;
92
+ }
93
+
94
+
95
+ static ngx_int_t
96
+ ngx_stream_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
97
+ {
98
+ ngx_stream_upstream_rr_peer_data_t *rrp = data;
99
+
100
+ time_t now;
101
+ uintptr_t m;
102
+ ngx_int_t rc, total;
103
+ ngx_uint_t i, n, p, many;
104
+ ngx_stream_upstream_rr_peer_t *peer, *best;
105
+ ngx_stream_upstream_rr_peers_t *peers;
106
+
107
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
108
+ "get least conn peer, try: %ui", pc->tries);
109
+
110
+ if (rrp->peers->single) {
111
+ return ngx_stream_upstream_get_round_robin_peer(pc, rrp);
112
+ }
113
+
114
+ pc->connection = NULL;
115
+
116
+ now = ngx_time();
117
+
118
+ peers = rrp->peers;
119
+
120
+ ngx_stream_upstream_rr_peers_wlock(peers);
121
+
122
+ best = NULL;
123
+ total = 0;
124
+
125
+ #if (NGX_SUPPRESS_WARN)
126
+ many = 0;
127
+ p = 0;
128
+ #endif
129
+
130
+ for (peer = peers->peer, i = 0;
131
+ peer;
132
+ peer = peer->next, i++)
133
+ {
134
+
135
+ n = i / (8 * sizeof(uintptr_t));
136
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
137
+
138
+ if (rrp->tried[n] & m) {
139
+ continue;
140
+ }
141
+
142
+ if (peer->down) {
143
+ continue;
144
+ }
145
+
146
+ if (peer->max_fails
147
+ && peer->fails >= peer->max_fails
148
+ && now - peer->checked <= peer->fail_timeout)
149
+ {
150
+ continue;
151
+ }
152
+
153
+ /*
154
+ * select peer with least number of connections; if there are
155
+ * multiple peers with the same number of connections, select
156
+ * based on round-robin
157
+ */
158
+
159
+ if (best == NULL
160
+ || peer->conns * best->weight < best->conns * peer->weight)
161
+ {
162
+ best = peer;
163
+ many = 0;
164
+ p = i;
165
+
166
+ } else if (peer->conns * best->weight == best->conns * peer->weight) {
167
+ many = 1;
168
+ }
169
+ }
170
+
171
+ if (best == NULL) {
172
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0,
173
+ "get least conn peer, no peer found");
174
+
175
+ goto failed;
176
+ }
177
+
178
+ if (many) {
179
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0,
180
+ "get least conn peer, many");
181
+
182
+ for (peer = best, i = p;
183
+ peer;
184
+ peer = peer->next, i++)
185
+ {
186
+ n = i / (8 * sizeof(uintptr_t));
187
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
188
+
189
+ if (rrp->tried[n] & m) {
190
+ continue;
191
+ }
192
+
193
+ if (peer->down) {
194
+ continue;
195
+ }
196
+
197
+ if (peer->conns * best->weight != best->conns * peer->weight) {
198
+ continue;
199
+ }
200
+
201
+ if (peer->max_fails
202
+ && peer->fails >= peer->max_fails
203
+ && now - peer->checked <= peer->fail_timeout)
204
+ {
205
+ continue;
206
+ }
207
+
208
+ peer->current_weight += peer->effective_weight;
209
+ total += peer->effective_weight;
210
+
211
+ if (peer->effective_weight < peer->weight) {
212
+ peer->effective_weight++;
213
+ }
214
+
215
+ if (peer->current_weight > best->current_weight) {
216
+ best = peer;
217
+ p = i;
218
+ }
219
+ }
220
+ }
221
+
222
+ best->current_weight -= total;
223
+
224
+ if (now - best->checked > best->fail_timeout) {
225
+ best->checked = now;
226
+ }
227
+
228
+ pc->sockaddr = best->sockaddr;
229
+ pc->socklen = best->socklen;
230
+ pc->name = &best->name;
231
+
232
+ best->conns++;
233
+
234
+ rrp->current = best;
235
+
236
+ n = p / (8 * sizeof(uintptr_t));
237
+ m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
238
+
239
+ rrp->tried[n] |= m;
240
+
241
+ ngx_stream_upstream_rr_peers_unlock(peers);
242
+
243
+ return NGX_OK;
244
+
245
+ failed:
246
+
247
+ if (peers->next) {
248
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0,
249
+ "get least conn peer, backup servers");
250
+
251
+ rrp->peers = peers->next;
252
+
253
+ n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
254
+ / (8 * sizeof(uintptr_t));
255
+
256
+ for (i = 0; i < n; i++) {
257
+ rrp->tried[i] = 0;
258
+ }
259
+
260
+ ngx_stream_upstream_rr_peers_unlock(peers);
261
+
262
+ rc = ngx_stream_upstream_get_least_conn_peer(pc, rrp);
263
+
264
+ if (rc != NGX_BUSY) {
265
+ return rc;
266
+ }
267
+
268
+ ngx_stream_upstream_rr_peers_wlock(peers);
269
+ }
270
+
271
+ /* all peers failed, mark them as live for quick recovery */
272
+
273
+ for (peer = peers->peer; peer; peer = peer->next) {
274
+ peer->fails = 0;
275
+ }
276
+
277
+ ngx_stream_upstream_rr_peers_unlock(peers);
278
+
279
+ pc->name = peers->name;
280
+
281
+ return NGX_BUSY;
282
+ }
283
+
284
+
285
+ static char *
286
+ ngx_stream_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
287
+ {
288
+ ngx_stream_upstream_srv_conf_t *uscf;
289
+
290
+ uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module);
291
+
292
+ if (uscf->peer.init_upstream) {
293
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
294
+ "load balancing method redefined");
295
+ }
296
+
297
+ uscf->peer.init_upstream = ngx_stream_upstream_init_least_conn;
298
+
299
+ uscf->flags = NGX_STREAM_UPSTREAM_CREATE
300
+ |NGX_STREAM_UPSTREAM_WEIGHT
301
+ |NGX_STREAM_UPSTREAM_MAX_FAILS
302
+ |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
303
+ |NGX_STREAM_UPSTREAM_DOWN
304
+ |NGX_STREAM_UPSTREAM_BACKUP;
305
+
306
+ return NGX_CONF_OK;
307
+ }
@@ -0,0 +1,702 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
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
+ #define ngx_stream_upstream_tries(p) ((p)->number \
14
+ + ((p)->next ? (p)->next->number : 0))
15
+
16
+
17
+ static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer(
18
+ ngx_stream_upstream_rr_peer_data_t *rrp);
19
+
20
+ #if (NGX_STREAM_SSL)
21
+
22
+ static ngx_int_t ngx_stream_upstream_set_round_robin_peer_session(
23
+ ngx_peer_connection_t *pc, void *data);
24
+ static void ngx_stream_upstream_save_round_robin_peer_session(
25
+ ngx_peer_connection_t *pc, void *data);
26
+
27
+ #endif
28
+
29
+
30
+ ngx_int_t
31
+ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
32
+ ngx_stream_upstream_srv_conf_t *us)
33
+ {
34
+ ngx_url_t u;
35
+ ngx_uint_t i, j, n, w;
36
+ ngx_stream_upstream_server_t *server;
37
+ ngx_stream_upstream_rr_peer_t *peer, **peerp;
38
+ ngx_stream_upstream_rr_peers_t *peers, *backup;
39
+
40
+ us->peer.init = ngx_stream_upstream_init_round_robin_peer;
41
+
42
+ if (us->servers) {
43
+ server = us->servers->elts;
44
+
45
+ n = 0;
46
+ w = 0;
47
+
48
+ for (i = 0; i < us->servers->nelts; i++) {
49
+ if (server[i].backup) {
50
+ continue;
51
+ }
52
+
53
+ n += server[i].naddrs;
54
+ w += server[i].naddrs * server[i].weight;
55
+ }
56
+
57
+ if (n == 0) {
58
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
59
+ "no servers in upstream \"%V\" in %s:%ui",
60
+ &us->host, us->file_name, us->line);
61
+ return NGX_ERROR;
62
+ }
63
+
64
+ peers = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t));
65
+ if (peers == NULL) {
66
+ return NGX_ERROR;
67
+ }
68
+
69
+ peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n);
70
+ if (peer == NULL) {
71
+ return NGX_ERROR;
72
+ }
73
+
74
+ peers->single = (n == 1);
75
+ peers->number = n;
76
+ peers->weighted = (w != n);
77
+ peers->total_weight = w;
78
+ peers->name = &us->host;
79
+
80
+ n = 0;
81
+ peerp = &peers->peer;
82
+
83
+ for (i = 0; i < us->servers->nelts; i++) {
84
+ if (server[i].backup) {
85
+ continue;
86
+ }
87
+
88
+ for (j = 0; j < server[i].naddrs; j++) {
89
+ peer[n].sockaddr = server[i].addrs[j].sockaddr;
90
+ peer[n].socklen = server[i].addrs[j].socklen;
91
+ peer[n].name = server[i].addrs[j].name;
92
+ peer[n].weight = server[i].weight;
93
+ peer[n].effective_weight = server[i].weight;
94
+ peer[n].current_weight = 0;
95
+ peer[n].max_fails = server[i].max_fails;
96
+ peer[n].fail_timeout = server[i].fail_timeout;
97
+ peer[n].down = server[i].down;
98
+ peer[n].server = server[i].name;
99
+
100
+ *peerp = &peer[n];
101
+ peerp = &peer[n].next;
102
+ n++;
103
+ }
104
+ }
105
+
106
+ us->peer.data = peers;
107
+
108
+ /* backup servers */
109
+
110
+ n = 0;
111
+ w = 0;
112
+
113
+ for (i = 0; i < us->servers->nelts; i++) {
114
+ if (!server[i].backup) {
115
+ continue;
116
+ }
117
+
118
+ n += server[i].naddrs;
119
+ w += server[i].naddrs * server[i].weight;
120
+ }
121
+
122
+ if (n == 0) {
123
+ return NGX_OK;
124
+ }
125
+
126
+ backup = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t));
127
+ if (backup == NULL) {
128
+ return NGX_ERROR;
129
+ }
130
+
131
+ peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n);
132
+ if (peer == NULL) {
133
+ return NGX_ERROR;
134
+ }
135
+
136
+ peers->single = 0;
137
+ backup->single = 0;
138
+ backup->number = n;
139
+ backup->weighted = (w != n);
140
+ backup->total_weight = w;
141
+ backup->name = &us->host;
142
+
143
+ n = 0;
144
+ peerp = &backup->peer;
145
+
146
+ for (i = 0; i < us->servers->nelts; i++) {
147
+ if (!server[i].backup) {
148
+ continue;
149
+ }
150
+
151
+ for (j = 0; j < server[i].naddrs; j++) {
152
+ peer[n].sockaddr = server[i].addrs[j].sockaddr;
153
+ peer[n].socklen = server[i].addrs[j].socklen;
154
+ peer[n].name = server[i].addrs[j].name;
155
+ peer[n].weight = server[i].weight;
156
+ peer[n].effective_weight = server[i].weight;
157
+ peer[n].current_weight = 0;
158
+ peer[n].max_fails = server[i].max_fails;
159
+ peer[n].fail_timeout = server[i].fail_timeout;
160
+ peer[n].down = server[i].down;
161
+ peer[n].server = server[i].name;
162
+
163
+ *peerp = &peer[n];
164
+ peerp = &peer[n].next;
165
+ n++;
166
+ }
167
+ }
168
+
169
+ peers->next = backup;
170
+
171
+ return NGX_OK;
172
+ }
173
+
174
+
175
+ /* an upstream implicitly defined by proxy_pass, etc. */
176
+
177
+ if (us->port == 0) {
178
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
179
+ "no port in upstream \"%V\" in %s:%ui",
180
+ &us->host, us->file_name, us->line);
181
+ return NGX_ERROR;
182
+ }
183
+
184
+ ngx_memzero(&u, sizeof(ngx_url_t));
185
+
186
+ u.host = us->host;
187
+ u.port = us->port;
188
+
189
+ if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
190
+ if (u.err) {
191
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
192
+ "%s in upstream \"%V\" in %s:%ui",
193
+ u.err, &us->host, us->file_name, us->line);
194
+ }
195
+
196
+ return NGX_ERROR;
197
+ }
198
+
199
+ n = u.naddrs;
200
+
201
+ peers = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t));
202
+ if (peers == NULL) {
203
+ return NGX_ERROR;
204
+ }
205
+
206
+ peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n);
207
+ if (peer == NULL) {
208
+ return NGX_ERROR;
209
+ }
210
+
211
+ peers->single = (n == 1);
212
+ peers->number = n;
213
+ peers->weighted = 0;
214
+ peers->total_weight = n;
215
+ peers->name = &us->host;
216
+
217
+ peerp = &peers->peer;
218
+
219
+ for (i = 0; i < u.naddrs; i++) {
220
+ peer[i].sockaddr = u.addrs[i].sockaddr;
221
+ peer[i].socklen = u.addrs[i].socklen;
222
+ peer[i].name = u.addrs[i].name;
223
+ peer[i].weight = 1;
224
+ peer[i].effective_weight = 1;
225
+ peer[i].current_weight = 0;
226
+ peer[i].max_fails = 1;
227
+ peer[i].fail_timeout = 10;
228
+ *peerp = &peer[i];
229
+ peerp = &peer[i].next;
230
+ }
231
+
232
+ us->peer.data = peers;
233
+
234
+ /* implicitly defined upstream has no backup servers */
235
+
236
+ return NGX_OK;
237
+ }
238
+
239
+
240
+ ngx_int_t
241
+ ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s,
242
+ ngx_stream_upstream_srv_conf_t *us)
243
+ {
244
+ ngx_uint_t n;
245
+ ngx_stream_upstream_rr_peer_data_t *rrp;
246
+
247
+ rrp = s->upstream->peer.data;
248
+
249
+ if (rrp == NULL) {
250
+ rrp = ngx_palloc(s->connection->pool,
251
+ sizeof(ngx_stream_upstream_rr_peer_data_t));
252
+ if (rrp == NULL) {
253
+ return NGX_ERROR;
254
+ }
255
+
256
+ s->upstream->peer.data = rrp;
257
+ }
258
+
259
+ rrp->peers = us->peer.data;
260
+ rrp->current = NULL;
261
+
262
+ n = rrp->peers->number;
263
+
264
+ if (rrp->peers->next && rrp->peers->next->number > n) {
265
+ n = rrp->peers->next->number;
266
+ }
267
+
268
+ if (n <= 8 * sizeof(uintptr_t)) {
269
+ rrp->tried = &rrp->data;
270
+ rrp->data = 0;
271
+
272
+ } else {
273
+ n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t));
274
+
275
+ rrp->tried = ngx_pcalloc(s->connection->pool, n * sizeof(uintptr_t));
276
+ if (rrp->tried == NULL) {
277
+ return NGX_ERROR;
278
+ }
279
+ }
280
+
281
+ s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer;
282
+ s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer;
283
+ s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers);
284
+ #if (NGX_STREAM_SSL)
285
+ s->upstream->peer.set_session =
286
+ ngx_stream_upstream_set_round_robin_peer_session;
287
+ s->upstream->peer.save_session =
288
+ ngx_stream_upstream_save_round_robin_peer_session;
289
+ #endif
290
+
291
+ return NGX_OK;
292
+ }
293
+
294
+
295
+ ngx_int_t
296
+ ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
297
+ {
298
+ ngx_stream_upstream_rr_peer_data_t *rrp = data;
299
+
300
+ ngx_int_t rc;
301
+ ngx_uint_t i, n;
302
+ ngx_stream_upstream_rr_peer_t *peer;
303
+ ngx_stream_upstream_rr_peers_t *peers;
304
+
305
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
306
+ "get rr peer, try: %ui", pc->tries);
307
+
308
+ pc->connection = NULL;
309
+
310
+ peers = rrp->peers;
311
+ ngx_stream_upstream_rr_peers_wlock(peers);
312
+
313
+ if (peers->single) {
314
+ peer = peers->peer;
315
+
316
+ if (peer->down) {
317
+ goto failed;
318
+ }
319
+
320
+ rrp->current = peer;
321
+
322
+ } else {
323
+
324
+ /* there are several peers */
325
+
326
+ peer = ngx_stream_upstream_get_peer(rrp);
327
+
328
+ if (peer == NULL) {
329
+ goto failed;
330
+ }
331
+
332
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0,
333
+ "get rr peer, current: %p %i",
334
+ peer, peer->current_weight);
335
+ }
336
+
337
+ pc->sockaddr = peer->sockaddr;
338
+ pc->socklen = peer->socklen;
339
+ pc->name = &peer->name;
340
+
341
+ peer->conns++;
342
+
343
+ ngx_stream_upstream_rr_peers_unlock(peers);
344
+
345
+ return NGX_OK;
346
+
347
+ failed:
348
+
349
+ if (peers->next) {
350
+
351
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "backup servers");
352
+
353
+ rrp->peers = peers->next;
354
+
355
+ n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
356
+ / (8 * sizeof(uintptr_t));
357
+
358
+ for (i = 0; i < n; i++) {
359
+ rrp->tried[i] = 0;
360
+ }
361
+
362
+ ngx_stream_upstream_rr_peers_unlock(peers);
363
+
364
+ rc = ngx_stream_upstream_get_round_robin_peer(pc, rrp);
365
+
366
+ if (rc != NGX_BUSY) {
367
+ return rc;
368
+ }
369
+
370
+ ngx_stream_upstream_rr_peers_wlock(peers);
371
+ }
372
+
373
+ /* all peers failed, mark them as live for quick recovery */
374
+
375
+ for (peer = peers->peer; peer; peer = peer->next) {
376
+ peer->fails = 0;
377
+ }
378
+
379
+ ngx_stream_upstream_rr_peers_unlock(peers);
380
+
381
+ pc->name = peers->name;
382
+
383
+ return NGX_BUSY;
384
+ }
385
+
386
+
387
+ static ngx_stream_upstream_rr_peer_t *
388
+ ngx_stream_upstream_get_peer(ngx_stream_upstream_rr_peer_data_t *rrp)
389
+ {
390
+ time_t now;
391
+ uintptr_t m;
392
+ ngx_int_t total;
393
+ ngx_uint_t i, n, p;
394
+ ngx_stream_upstream_rr_peer_t *peer, *best;
395
+
396
+ now = ngx_time();
397
+
398
+ best = NULL;
399
+ total = 0;
400
+
401
+ #if (NGX_SUPPRESS_WARN)
402
+ p = 0;
403
+ #endif
404
+
405
+ for (peer = rrp->peers->peer, i = 0;
406
+ peer;
407
+ peer = peer->next, i++)
408
+ {
409
+
410
+ n = i / (8 * sizeof(uintptr_t));
411
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
412
+
413
+ if (rrp->tried[n] & m) {
414
+ continue;
415
+ }
416
+
417
+ if (peer->down) {
418
+ continue;
419
+ }
420
+
421
+ if (peer->max_fails
422
+ && peer->fails >= peer->max_fails
423
+ && now - peer->checked <= peer->fail_timeout)
424
+ {
425
+ continue;
426
+ }
427
+
428
+ peer->current_weight += peer->effective_weight;
429
+ total += peer->effective_weight;
430
+
431
+ if (peer->effective_weight < peer->weight) {
432
+ peer->effective_weight++;
433
+ }
434
+
435
+ if (best == NULL || peer->current_weight > best->current_weight) {
436
+ best = peer;
437
+ p = i;
438
+ }
439
+ }
440
+
441
+ if (best == NULL) {
442
+ return NULL;
443
+ }
444
+
445
+ rrp->current = best;
446
+
447
+ n = p / (8 * sizeof(uintptr_t));
448
+ m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
449
+
450
+ rrp->tried[n] |= m;
451
+
452
+ best->current_weight -= total;
453
+
454
+ if (now - best->checked > best->fail_timeout) {
455
+ best->checked = now;
456
+ }
457
+
458
+ return best;
459
+ }
460
+
461
+
462
+ void
463
+ ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
464
+ ngx_uint_t state)
465
+ {
466
+ ngx_stream_upstream_rr_peer_data_t *rrp = data;
467
+
468
+ time_t now;
469
+ ngx_stream_upstream_rr_peer_t *peer;
470
+
471
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0,
472
+ "free rr peer %ui %ui", pc->tries, state);
473
+
474
+ peer = rrp->current;
475
+
476
+ ngx_stream_upstream_rr_peers_rlock(rrp->peers);
477
+ ngx_stream_upstream_rr_peer_lock(rrp->peers, peer);
478
+
479
+ if (rrp->peers->single) {
480
+ peer->conns--;
481
+
482
+ ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer);
483
+ ngx_stream_upstream_rr_peers_unlock(rrp->peers);
484
+
485
+ pc->tries = 0;
486
+ return;
487
+ }
488
+
489
+ if (state & NGX_PEER_FAILED) {
490
+ now = ngx_time();
491
+
492
+ peer->fails++;
493
+ peer->accessed = now;
494
+ peer->checked = now;
495
+
496
+ if (peer->max_fails) {
497
+ peer->effective_weight -= peer->weight / peer->max_fails;
498
+
499
+ if (peer->fails >= peer->max_fails) {
500
+ ngx_log_error(NGX_LOG_WARN, pc->log, 0,
501
+ "upstream server temporarily disabled");
502
+ }
503
+ }
504
+
505
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0,
506
+ "free rr peer failed: %p %i",
507
+ peer, peer->effective_weight);
508
+
509
+ if (peer->effective_weight < 0) {
510
+ peer->effective_weight = 0;
511
+ }
512
+
513
+ } else {
514
+
515
+ /* mark peer live if check passed */
516
+
517
+ if (peer->accessed < peer->checked) {
518
+ peer->fails = 0;
519
+ }
520
+ }
521
+
522
+ peer->conns--;
523
+
524
+ ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer);
525
+ ngx_stream_upstream_rr_peers_unlock(rrp->peers);
526
+
527
+ if (pc->tries) {
528
+ pc->tries--;
529
+ }
530
+ }
531
+
532
+
533
+ #if (NGX_STREAM_SSL)
534
+
535
+ static ngx_int_t
536
+ ngx_stream_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
537
+ void *data)
538
+ {
539
+ ngx_stream_upstream_rr_peer_data_t *rrp = data;
540
+
541
+ ngx_int_t rc;
542
+ ngx_ssl_session_t *ssl_session;
543
+ ngx_stream_upstream_rr_peer_t *peer;
544
+ #if (NGX_STREAM_UPSTREAM_ZONE)
545
+ int len;
546
+ #if OPENSSL_VERSION_NUMBER >= 0x0090707fL
547
+ const
548
+ #endif
549
+ u_char *p;
550
+ ngx_stream_upstream_rr_peers_t *peers;
551
+ u_char buf[NGX_SSL_MAX_SESSION_SIZE];
552
+ #endif
553
+
554
+ peer = rrp->current;
555
+
556
+ #if (NGX_STREAM_UPSTREAM_ZONE)
557
+ peers = rrp->peers;
558
+
559
+ if (peers->shpool) {
560
+ ngx_stream_upstream_rr_peers_rlock(peers);
561
+ ngx_stream_upstream_rr_peer_lock(peers, peer);
562
+
563
+ if (peer->ssl_session == NULL) {
564
+ ngx_stream_upstream_rr_peer_unlock(peers, peer);
565
+ ngx_stream_upstream_rr_peers_unlock(peers);
566
+ return NGX_OK;
567
+ }
568
+
569
+ len = peer->ssl_session_len;
570
+
571
+ ngx_memcpy(buf, peer->ssl_session, len);
572
+
573
+ ngx_stream_upstream_rr_peer_unlock(peers, peer);
574
+ ngx_stream_upstream_rr_peers_unlock(peers);
575
+
576
+ p = buf;
577
+ ssl_session = d2i_SSL_SESSION(NULL, &p, len);
578
+
579
+ rc = ngx_ssl_set_session(pc->connection, ssl_session);
580
+
581
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
582
+ "set session: %p", ssl_session);
583
+
584
+ ngx_ssl_free_session(ssl_session);
585
+
586
+ return rc;
587
+ }
588
+ #endif
589
+
590
+ ssl_session = peer->ssl_session;
591
+
592
+ rc = ngx_ssl_set_session(pc->connection, ssl_session);
593
+
594
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
595
+ "set session: %p", ssl_session);
596
+
597
+ return rc;
598
+ }
599
+
600
+
601
+ static void
602
+ ngx_stream_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
603
+ void *data)
604
+ {
605
+ ngx_stream_upstream_rr_peer_data_t *rrp = data;
606
+
607
+ ngx_ssl_session_t *old_ssl_session, *ssl_session;
608
+ ngx_stream_upstream_rr_peer_t *peer;
609
+ #if (NGX_STREAM_UPSTREAM_ZONE)
610
+ int len;
611
+ u_char *p;
612
+ ngx_stream_upstream_rr_peers_t *peers;
613
+ u_char buf[NGX_SSL_MAX_SESSION_SIZE];
614
+ #endif
615
+
616
+ #if (NGX_STREAM_UPSTREAM_ZONE)
617
+ peers = rrp->peers;
618
+
619
+ if (peers->shpool) {
620
+
621
+ ssl_session = SSL_get0_session(pc->connection->ssl->connection);
622
+
623
+ if (ssl_session == NULL) {
624
+ return;
625
+ }
626
+
627
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
628
+ "save session: %p", ssl_session);
629
+
630
+ len = i2d_SSL_SESSION(ssl_session, NULL);
631
+
632
+ /* do not cache too big session */
633
+
634
+ if (len > NGX_SSL_MAX_SESSION_SIZE) {
635
+ return;
636
+ }
637
+
638
+ p = buf;
639
+ (void) i2d_SSL_SESSION(ssl_session, &p);
640
+
641
+ peer = rrp->current;
642
+
643
+ ngx_stream_upstream_rr_peers_rlock(peers);
644
+ ngx_stream_upstream_rr_peer_lock(peers, peer);
645
+
646
+ if (len > peer->ssl_session_len) {
647
+ ngx_shmtx_lock(&peers->shpool->mutex);
648
+
649
+ if (peer->ssl_session) {
650
+ ngx_slab_free_locked(peers->shpool, peer->ssl_session);
651
+ }
652
+
653
+ peer->ssl_session = ngx_slab_alloc_locked(peers->shpool, len);
654
+
655
+ ngx_shmtx_unlock(&peers->shpool->mutex);
656
+
657
+ if (peer->ssl_session == NULL) {
658
+ peer->ssl_session_len = 0;
659
+
660
+ ngx_stream_upstream_rr_peer_unlock(peers, peer);
661
+ ngx_stream_upstream_rr_peers_unlock(peers);
662
+ return;
663
+ }
664
+
665
+ peer->ssl_session_len = len;
666
+ }
667
+
668
+ ngx_memcpy(peer->ssl_session, buf, len);
669
+
670
+ ngx_stream_upstream_rr_peer_unlock(peers, peer);
671
+ ngx_stream_upstream_rr_peers_unlock(peers);
672
+
673
+ return;
674
+ }
675
+ #endif
676
+
677
+ ssl_session = ngx_ssl_get_session(pc->connection);
678
+
679
+ if (ssl_session == NULL) {
680
+ return;
681
+ }
682
+
683
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
684
+ "save session: %p", ssl_session);
685
+
686
+ peer = rrp->current;
687
+
688
+ old_ssl_session = peer->ssl_session;
689
+ peer->ssl_session = ssl_session;
690
+
691
+ if (old_ssl_session) {
692
+
693
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0,
694
+ "old session: %p", old_ssl_session);
695
+
696
+ /* TODO: may block */
697
+
698
+ ngx_ssl_free_session(old_ssl_session);
699
+ }
700
+ }
701
+
702
+ #endif