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,1674 @@
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
+ ngx_msec_t connect_timeout;
15
+ ngx_msec_t timeout;
16
+ ngx_msec_t next_upstream_timeout;
17
+ size_t buffer_size;
18
+ size_t upload_rate;
19
+ size_t download_rate;
20
+ ngx_uint_t responses;
21
+ ngx_uint_t next_upstream_tries;
22
+ ngx_flag_t next_upstream;
23
+ ngx_flag_t proxy_protocol;
24
+ ngx_addr_t *local;
25
+
26
+ #if (NGX_STREAM_SSL)
27
+ ngx_flag_t ssl_enable;
28
+ ngx_flag_t ssl_session_reuse;
29
+ ngx_uint_t ssl_protocols;
30
+ ngx_str_t ssl_ciphers;
31
+ ngx_str_t ssl_name;
32
+ ngx_flag_t ssl_server_name;
33
+
34
+ ngx_flag_t ssl_verify;
35
+ ngx_uint_t ssl_verify_depth;
36
+ ngx_str_t ssl_trusted_certificate;
37
+ ngx_str_t ssl_crl;
38
+ ngx_str_t ssl_certificate;
39
+ ngx_str_t ssl_certificate_key;
40
+ ngx_array_t *ssl_passwords;
41
+
42
+ ngx_ssl_t *ssl;
43
+ #endif
44
+
45
+ ngx_stream_upstream_srv_conf_t *upstream;
46
+ } ngx_stream_proxy_srv_conf_t;
47
+
48
+
49
+ static void ngx_stream_proxy_handler(ngx_stream_session_t *s);
50
+ static void ngx_stream_proxy_connect(ngx_stream_session_t *s);
51
+ static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s);
52
+ static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev);
53
+ static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev);
54
+ static void ngx_stream_proxy_process_connection(ngx_event_t *ev,
55
+ ngx_uint_t from_upstream);
56
+ static void ngx_stream_proxy_connect_handler(ngx_event_t *ev);
57
+ static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c);
58
+ static void ngx_stream_proxy_process(ngx_stream_session_t *s,
59
+ ngx_uint_t from_upstream, ngx_uint_t do_write);
60
+ static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
61
+ static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc);
62
+ static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
63
+ size_t len);
64
+
65
+ static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf);
66
+ static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent,
67
+ void *child);
68
+ static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
69
+ void *conf);
70
+ static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd,
71
+ void *conf);
72
+ static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
73
+
74
+ #if (NGX_STREAM_SSL)
75
+
76
+ static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
77
+ ngx_command_t *cmd, void *conf);
78
+ static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
79
+ static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
80
+ static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
81
+ static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
82
+ ngx_stream_proxy_srv_conf_t *pscf);
83
+
84
+
85
+ static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = {
86
+ { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
87
+ { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
88
+ { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
89
+ { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
90
+ { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
91
+ { ngx_null_string, 0 }
92
+ };
93
+
94
+ #endif
95
+
96
+
97
+ static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_downstream_buffer = {
98
+ ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
99
+ };
100
+
101
+ static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_upstream_buffer = {
102
+ ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
103
+ };
104
+
105
+
106
+ static ngx_command_t ngx_stream_proxy_commands[] = {
107
+
108
+ { ngx_string("proxy_pass"),
109
+ NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
110
+ ngx_stream_proxy_pass,
111
+ NGX_STREAM_SRV_CONF_OFFSET,
112
+ 0,
113
+ NULL },
114
+
115
+ { ngx_string("proxy_bind"),
116
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
117
+ ngx_stream_proxy_bind,
118
+ NGX_STREAM_SRV_CONF_OFFSET,
119
+ 0,
120
+ NULL },
121
+
122
+ { ngx_string("proxy_connect_timeout"),
123
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
124
+ ngx_conf_set_msec_slot,
125
+ NGX_STREAM_SRV_CONF_OFFSET,
126
+ offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
127
+ NULL },
128
+
129
+ { ngx_string("proxy_timeout"),
130
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
131
+ ngx_conf_set_msec_slot,
132
+ NGX_STREAM_SRV_CONF_OFFSET,
133
+ offsetof(ngx_stream_proxy_srv_conf_t, timeout),
134
+ NULL },
135
+
136
+ { ngx_string("proxy_buffer_size"),
137
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
138
+ ngx_conf_set_size_slot,
139
+ NGX_STREAM_SRV_CONF_OFFSET,
140
+ offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
141
+ NULL },
142
+
143
+ { ngx_string("proxy_downstream_buffer"),
144
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
145
+ ngx_conf_set_size_slot,
146
+ NGX_STREAM_SRV_CONF_OFFSET,
147
+ offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
148
+ &ngx_conf_deprecated_proxy_downstream_buffer },
149
+
150
+ { ngx_string("proxy_upstream_buffer"),
151
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
152
+ ngx_conf_set_size_slot,
153
+ NGX_STREAM_SRV_CONF_OFFSET,
154
+ offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
155
+ &ngx_conf_deprecated_proxy_upstream_buffer },
156
+
157
+ { ngx_string("proxy_upload_rate"),
158
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
159
+ ngx_conf_set_size_slot,
160
+ NGX_STREAM_SRV_CONF_OFFSET,
161
+ offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
162
+ NULL },
163
+
164
+ { ngx_string("proxy_download_rate"),
165
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
166
+ ngx_conf_set_size_slot,
167
+ NGX_STREAM_SRV_CONF_OFFSET,
168
+ offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
169
+ NULL },
170
+
171
+ { ngx_string("proxy_responses"),
172
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
173
+ ngx_conf_set_num_slot,
174
+ NGX_STREAM_SRV_CONF_OFFSET,
175
+ offsetof(ngx_stream_proxy_srv_conf_t, responses),
176
+ NULL },
177
+
178
+ { ngx_string("proxy_next_upstream"),
179
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
180
+ ngx_conf_set_flag_slot,
181
+ NGX_STREAM_SRV_CONF_OFFSET,
182
+ offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
183
+ NULL },
184
+
185
+ { ngx_string("proxy_next_upstream_tries"),
186
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
187
+ ngx_conf_set_num_slot,
188
+ NGX_STREAM_SRV_CONF_OFFSET,
189
+ offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
190
+ NULL },
191
+
192
+ { ngx_string("proxy_next_upstream_timeout"),
193
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
194
+ ngx_conf_set_msec_slot,
195
+ NGX_STREAM_SRV_CONF_OFFSET,
196
+ offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
197
+ NULL },
198
+
199
+ { ngx_string("proxy_protocol"),
200
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
201
+ ngx_conf_set_flag_slot,
202
+ NGX_STREAM_SRV_CONF_OFFSET,
203
+ offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
204
+ NULL },
205
+
206
+ #if (NGX_STREAM_SSL)
207
+
208
+ { ngx_string("proxy_ssl"),
209
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
210
+ ngx_conf_set_flag_slot,
211
+ NGX_STREAM_SRV_CONF_OFFSET,
212
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
213
+ NULL },
214
+
215
+ { ngx_string("proxy_ssl_session_reuse"),
216
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
217
+ ngx_conf_set_flag_slot,
218
+ NGX_STREAM_SRV_CONF_OFFSET,
219
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
220
+ NULL },
221
+
222
+ { ngx_string("proxy_ssl_protocols"),
223
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
224
+ ngx_conf_set_bitmask_slot,
225
+ NGX_STREAM_SRV_CONF_OFFSET,
226
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
227
+ &ngx_stream_proxy_ssl_protocols },
228
+
229
+ { ngx_string("proxy_ssl_ciphers"),
230
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
231
+ ngx_conf_set_str_slot,
232
+ NGX_STREAM_SRV_CONF_OFFSET,
233
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
234
+ NULL },
235
+
236
+ { ngx_string("proxy_ssl_name"),
237
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
238
+ ngx_conf_set_str_slot,
239
+ NGX_STREAM_SRV_CONF_OFFSET,
240
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
241
+ NULL },
242
+
243
+ { ngx_string("proxy_ssl_server_name"),
244
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
245
+ ngx_conf_set_flag_slot,
246
+ NGX_STREAM_SRV_CONF_OFFSET,
247
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
248
+ NULL },
249
+
250
+ { ngx_string("proxy_ssl_verify"),
251
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
252
+ ngx_conf_set_flag_slot,
253
+ NGX_STREAM_SRV_CONF_OFFSET,
254
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
255
+ NULL },
256
+
257
+ { ngx_string("proxy_ssl_verify_depth"),
258
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
259
+ ngx_conf_set_num_slot,
260
+ NGX_STREAM_SRV_CONF_OFFSET,
261
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
262
+ NULL },
263
+
264
+ { ngx_string("proxy_ssl_trusted_certificate"),
265
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
266
+ ngx_conf_set_str_slot,
267
+ NGX_STREAM_SRV_CONF_OFFSET,
268
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
269
+ NULL },
270
+
271
+ { ngx_string("proxy_ssl_crl"),
272
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
273
+ ngx_conf_set_str_slot,
274
+ NGX_STREAM_SRV_CONF_OFFSET,
275
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
276
+ NULL },
277
+
278
+ { ngx_string("proxy_ssl_certificate"),
279
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
280
+ ngx_conf_set_str_slot,
281
+ NGX_STREAM_SRV_CONF_OFFSET,
282
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
283
+ NULL },
284
+
285
+ { ngx_string("proxy_ssl_certificate_key"),
286
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
287
+ ngx_conf_set_str_slot,
288
+ NGX_STREAM_SRV_CONF_OFFSET,
289
+ offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
290
+ NULL },
291
+
292
+ { ngx_string("proxy_ssl_password_file"),
293
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
294
+ ngx_stream_proxy_ssl_password_file,
295
+ NGX_STREAM_SRV_CONF_OFFSET,
296
+ 0,
297
+ NULL },
298
+
299
+ #endif
300
+
301
+ ngx_null_command
302
+ };
303
+
304
+
305
+ static ngx_stream_module_t ngx_stream_proxy_module_ctx = {
306
+ NULL, /* postconfiguration */
307
+
308
+ NULL, /* create main configuration */
309
+ NULL, /* init main configuration */
310
+
311
+ ngx_stream_proxy_create_srv_conf, /* create server configuration */
312
+ ngx_stream_proxy_merge_srv_conf /* merge server configuration */
313
+ };
314
+
315
+
316
+ ngx_module_t ngx_stream_proxy_module = {
317
+ NGX_MODULE_V1,
318
+ &ngx_stream_proxy_module_ctx, /* module context */
319
+ ngx_stream_proxy_commands, /* module directives */
320
+ NGX_STREAM_MODULE, /* module type */
321
+ NULL, /* init master */
322
+ NULL, /* init module */
323
+ NULL, /* init process */
324
+ NULL, /* init thread */
325
+ NULL, /* exit thread */
326
+ NULL, /* exit process */
327
+ NULL, /* exit master */
328
+ NGX_MODULE_V1_PADDING
329
+ };
330
+
331
+
332
+ static void
333
+ ngx_stream_proxy_handler(ngx_stream_session_t *s)
334
+ {
335
+ u_char *p;
336
+ ngx_connection_t *c;
337
+ ngx_stream_upstream_t *u;
338
+ ngx_stream_proxy_srv_conf_t *pscf;
339
+ ngx_stream_upstream_srv_conf_t *uscf;
340
+
341
+ c = s->connection;
342
+
343
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
344
+
345
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
346
+ "proxy connection handler");
347
+
348
+ u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
349
+ if (u == NULL) {
350
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
351
+ return;
352
+ }
353
+
354
+ s->upstream = u;
355
+
356
+ s->log_handler = ngx_stream_proxy_log_error;
357
+
358
+ u->peer.log = c->log;
359
+ u->peer.log_error = NGX_ERROR_ERR;
360
+
361
+ u->peer.local = pscf->local;
362
+ u->peer.type = c->type;
363
+
364
+ uscf = pscf->upstream;
365
+
366
+ if (uscf->peer.init(s, uscf) != NGX_OK) {
367
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
368
+ return;
369
+ }
370
+
371
+ u->peer.start_time = ngx_current_msec;
372
+
373
+ if (pscf->next_upstream_tries
374
+ && u->peer.tries > pscf->next_upstream_tries)
375
+ {
376
+ u->peer.tries = pscf->next_upstream_tries;
377
+ }
378
+
379
+ u->proxy_protocol = pscf->proxy_protocol;
380
+ u->start_sec = ngx_time();
381
+
382
+ c->write->handler = ngx_stream_proxy_downstream_handler;
383
+ c->read->handler = ngx_stream_proxy_downstream_handler;
384
+
385
+ if (c->type == SOCK_DGRAM) {
386
+ ngx_stream_proxy_connect(s);
387
+ return;
388
+ }
389
+
390
+ p = ngx_pnalloc(c->pool, pscf->buffer_size);
391
+ if (p == NULL) {
392
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
393
+ return;
394
+ }
395
+
396
+ u->downstream_buf.start = p;
397
+ u->downstream_buf.end = p + pscf->buffer_size;
398
+ u->downstream_buf.pos = p;
399
+ u->downstream_buf.last = p;
400
+
401
+ if (u->proxy_protocol
402
+ #if (NGX_STREAM_SSL)
403
+ && pscf->ssl == NULL
404
+ #endif
405
+ && pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER)
406
+ {
407
+ /* optimization for a typical case */
408
+
409
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
410
+ "stream proxy send PROXY protocol header");
411
+
412
+ p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
413
+ u->downstream_buf.end);
414
+ if (p == NULL) {
415
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
416
+ return;
417
+ }
418
+
419
+ u->downstream_buf.last = p;
420
+ u->proxy_protocol = 0;
421
+ }
422
+
423
+ if (c->read->ready) {
424
+ ngx_post_event(c->read, &ngx_posted_events);
425
+ }
426
+
427
+ ngx_stream_proxy_connect(s);
428
+ }
429
+
430
+
431
+ static void
432
+ ngx_stream_proxy_connect(ngx_stream_session_t *s)
433
+ {
434
+ ngx_int_t rc;
435
+ ngx_connection_t *c, *pc;
436
+ ngx_stream_upstream_t *u;
437
+ ngx_stream_proxy_srv_conf_t *pscf;
438
+
439
+ c = s->connection;
440
+
441
+ c->log->action = "connecting to upstream";
442
+
443
+ u = s->upstream;
444
+
445
+ rc = ngx_event_connect_peer(&u->peer);
446
+
447
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
448
+
449
+ if (rc == NGX_ERROR) {
450
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
451
+ return;
452
+ }
453
+
454
+ if (rc == NGX_BUSY) {
455
+ ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
456
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
457
+ return;
458
+ }
459
+
460
+ if (rc == NGX_DECLINED) {
461
+ ngx_stream_proxy_next_upstream(s);
462
+ return;
463
+ }
464
+
465
+ /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
466
+
467
+ pc = u->peer.connection;
468
+
469
+ pc->data = s;
470
+ pc->log = c->log;
471
+ pc->pool = c->pool;
472
+ pc->read->log = c->log;
473
+ pc->write->log = c->log;
474
+
475
+ if (rc != NGX_AGAIN) {
476
+ ngx_stream_proxy_init_upstream(s);
477
+ return;
478
+ }
479
+
480
+ pc->read->handler = ngx_stream_proxy_connect_handler;
481
+ pc->write->handler = ngx_stream_proxy_connect_handler;
482
+
483
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
484
+
485
+ ngx_add_timer(pc->write, pscf->connect_timeout);
486
+ }
487
+
488
+
489
+ static void
490
+ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
491
+ {
492
+ int tcp_nodelay;
493
+ u_char *p;
494
+ ngx_connection_t *c, *pc;
495
+ ngx_log_handler_pt handler;
496
+ ngx_stream_upstream_t *u;
497
+ ngx_stream_core_srv_conf_t *cscf;
498
+ ngx_stream_proxy_srv_conf_t *pscf;
499
+
500
+ u = s->upstream;
501
+ pc = u->peer.connection;
502
+
503
+ cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
504
+
505
+ if (pc->type == SOCK_STREAM
506
+ && cscf->tcp_nodelay
507
+ && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
508
+ {
509
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");
510
+
511
+ tcp_nodelay = 1;
512
+
513
+ if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY,
514
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
515
+ {
516
+ ngx_connection_error(pc, ngx_socket_errno,
517
+ "setsockopt(TCP_NODELAY) failed");
518
+ ngx_stream_proxy_next_upstream(s);
519
+ return;
520
+ }
521
+
522
+ pc->tcp_nodelay = NGX_TCP_NODELAY_SET;
523
+ }
524
+
525
+ if (u->proxy_protocol) {
526
+ if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
527
+ return;
528
+ }
529
+
530
+ u->proxy_protocol = 0;
531
+ }
532
+
533
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
534
+
535
+ #if (NGX_STREAM_SSL)
536
+ if (pc->type == SOCK_STREAM && pscf->ssl && pc->ssl == NULL) {
537
+ ngx_stream_proxy_ssl_init_connection(s);
538
+ return;
539
+ }
540
+ #endif
541
+
542
+ c = s->connection;
543
+
544
+ if (c->log->log_level >= NGX_LOG_INFO) {
545
+ ngx_str_t str;
546
+ u_char addr[NGX_SOCKADDR_STRLEN];
547
+
548
+ str.len = NGX_SOCKADDR_STRLEN;
549
+ str.data = addr;
550
+
551
+ if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
552
+ handler = c->log->handler;
553
+ c->log->handler = NULL;
554
+
555
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
556
+ "%sproxy %V connected to %V",
557
+ pc->type == SOCK_DGRAM ? "udp " : "",
558
+ &str, u->peer.name);
559
+
560
+ c->log->handler = handler;
561
+ }
562
+ }
563
+
564
+ c->log->action = "proxying connection";
565
+
566
+ if (u->upstream_buf.start == NULL) {
567
+ p = ngx_pnalloc(c->pool, pscf->buffer_size);
568
+ if (p == NULL) {
569
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
570
+ return;
571
+ }
572
+
573
+ u->upstream_buf.start = p;
574
+ u->upstream_buf.end = p + pscf->buffer_size;
575
+ u->upstream_buf.pos = p;
576
+ u->upstream_buf.last = p;
577
+ }
578
+
579
+ if (c->type == SOCK_DGRAM) {
580
+ s->received = c->buffer->last - c->buffer->pos;
581
+ u->downstream_buf = *c->buffer;
582
+
583
+ if (pscf->responses == 0) {
584
+ pc->read->ready = 0;
585
+ pc->read->eof = 1;
586
+ }
587
+ }
588
+
589
+ u->connected = 1;
590
+
591
+ pc->read->handler = ngx_stream_proxy_upstream_handler;
592
+ pc->write->handler = ngx_stream_proxy_upstream_handler;
593
+
594
+ if (pc->read->ready || pc->read->eof) {
595
+ ngx_post_event(pc->read, &ngx_posted_events);
596
+ }
597
+
598
+ ngx_stream_proxy_process(s, 0, 1);
599
+ }
600
+
601
+
602
+ static ngx_int_t
603
+ ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
604
+ {
605
+ u_char *p;
606
+ ssize_t n, size;
607
+ ngx_connection_t *c, *pc;
608
+ ngx_stream_upstream_t *u;
609
+ ngx_stream_proxy_srv_conf_t *pscf;
610
+ u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
611
+
612
+ c = s->connection;
613
+
614
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
615
+ "stream proxy send PROXY protocol header");
616
+
617
+ p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
618
+ if (p == NULL) {
619
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
620
+ return NGX_ERROR;
621
+ }
622
+
623
+ u = s->upstream;
624
+
625
+ pc = u->peer.connection;
626
+
627
+ size = p - buf;
628
+
629
+ n = pc->send(pc, buf, size);
630
+
631
+ if (n == NGX_AGAIN) {
632
+ if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
633
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
634
+ return NGX_ERROR;
635
+ }
636
+
637
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
638
+
639
+ ngx_add_timer(pc->write, pscf->timeout);
640
+
641
+ pc->write->handler = ngx_stream_proxy_connect_handler;
642
+
643
+ return NGX_AGAIN;
644
+ }
645
+
646
+ if (n == NGX_ERROR) {
647
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
648
+ return NGX_ERROR;
649
+ }
650
+
651
+ if (n != size) {
652
+
653
+ /*
654
+ * PROXY protocol specification:
655
+ * The sender must always ensure that the header
656
+ * is sent at once, so that the transport layer
657
+ * maintains atomicity along the path to the receiver.
658
+ */
659
+
660
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
661
+ "could not send PROXY protocol header at once");
662
+
663
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
664
+
665
+ return NGX_ERROR;
666
+ }
667
+
668
+ return NGX_OK;
669
+ }
670
+
671
+
672
+ #if (NGX_STREAM_SSL)
673
+
674
+ static char *
675
+ ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
676
+ void *conf)
677
+ {
678
+ ngx_stream_proxy_srv_conf_t *pscf = conf;
679
+
680
+ ngx_str_t *value;
681
+
682
+ if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
683
+ return "is duplicate";
684
+ }
685
+
686
+ value = cf->args->elts;
687
+
688
+ pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
689
+
690
+ if (pscf->ssl_passwords == NULL) {
691
+ return NGX_CONF_ERROR;
692
+ }
693
+
694
+ return NGX_CONF_OK;
695
+ }
696
+
697
+
698
+ static void
699
+ ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
700
+ {
701
+ ngx_int_t rc;
702
+ ngx_connection_t *pc;
703
+ ngx_stream_upstream_t *u;
704
+ ngx_stream_proxy_srv_conf_t *pscf;
705
+
706
+ u = s->upstream;
707
+
708
+ pc = u->peer.connection;
709
+
710
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
711
+
712
+ if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
713
+ != NGX_OK)
714
+ {
715
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
716
+ return;
717
+ }
718
+
719
+ if (pscf->ssl_server_name || pscf->ssl_verify) {
720
+ if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
721
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
722
+ return;
723
+ }
724
+ }
725
+
726
+ if (pscf->ssl_session_reuse) {
727
+ if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
728
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
729
+ return;
730
+ }
731
+ }
732
+
733
+ s->connection->log->action = "SSL handshaking to upstream";
734
+
735
+ rc = ngx_ssl_handshake(pc);
736
+
737
+ if (rc == NGX_AGAIN) {
738
+
739
+ if (!pc->write->timer_set) {
740
+ ngx_add_timer(pc->write, pscf->connect_timeout);
741
+ }
742
+
743
+ pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
744
+ return;
745
+ }
746
+
747
+ ngx_stream_proxy_ssl_handshake(pc);
748
+ }
749
+
750
+
751
+ static void
752
+ ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
753
+ {
754
+ long rc;
755
+ ngx_stream_session_t *s;
756
+ ngx_stream_upstream_t *u;
757
+ ngx_stream_proxy_srv_conf_t *pscf;
758
+
759
+ s = pc->data;
760
+
761
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
762
+
763
+ if (pc->ssl->handshaked) {
764
+
765
+ if (pscf->ssl_verify) {
766
+ rc = SSL_get_verify_result(pc->ssl->connection);
767
+
768
+ if (rc != X509_V_OK) {
769
+ ngx_log_error(NGX_LOG_ERR, pc->log, 0,
770
+ "upstream SSL certificate verify error: (%l:%s)",
771
+ rc, X509_verify_cert_error_string(rc));
772
+ goto failed;
773
+ }
774
+
775
+ u = s->upstream;
776
+
777
+ if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
778
+ ngx_log_error(NGX_LOG_ERR, pc->log, 0,
779
+ "upstream SSL certificate does not match \"%V\"",
780
+ &u->ssl_name);
781
+ goto failed;
782
+ }
783
+ }
784
+
785
+ if (pscf->ssl_session_reuse) {
786
+ u = s->upstream;
787
+ u->peer.save_session(&u->peer, u->peer.data);
788
+ }
789
+
790
+ if (pc->write->timer_set) {
791
+ ngx_del_timer(pc->write);
792
+ }
793
+
794
+ ngx_stream_proxy_init_upstream(s);
795
+
796
+ return;
797
+ }
798
+
799
+ failed:
800
+
801
+ ngx_stream_proxy_next_upstream(s);
802
+ }
803
+
804
+
805
+ static ngx_int_t
806
+ ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
807
+ {
808
+ u_char *p, *last;
809
+ ngx_str_t name;
810
+ ngx_stream_upstream_t *u;
811
+ ngx_stream_proxy_srv_conf_t *pscf;
812
+
813
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
814
+
815
+ u = s->upstream;
816
+
817
+ name = pscf->ssl_name;
818
+
819
+ if (name.len == 0) {
820
+ name = pscf->upstream->host;
821
+ }
822
+
823
+ if (name.len == 0) {
824
+ goto done;
825
+ }
826
+
827
+ /*
828
+ * ssl name here may contain port, strip it for compatibility
829
+ * with the http module
830
+ */
831
+
832
+ p = name.data;
833
+ last = name.data + name.len;
834
+
835
+ if (*p == '[') {
836
+ p = ngx_strlchr(p, last, ']');
837
+
838
+ if (p == NULL) {
839
+ p = name.data;
840
+ }
841
+ }
842
+
843
+ p = ngx_strlchr(p, last, ':');
844
+
845
+ if (p != NULL) {
846
+ name.len = p - name.data;
847
+ }
848
+
849
+ if (!pscf->ssl_server_name) {
850
+ goto done;
851
+ }
852
+
853
+ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
854
+
855
+ /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */
856
+
857
+ if (name.len == 0 || *name.data == '[') {
858
+ goto done;
859
+ }
860
+
861
+ if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
862
+ goto done;
863
+ }
864
+
865
+ /*
866
+ * SSL_set_tlsext_host_name() needs a null-terminated string,
867
+ * hence we explicitly null-terminate name here
868
+ */
869
+
870
+ p = ngx_pnalloc(s->connection->pool, name.len + 1);
871
+ if (p == NULL) {
872
+ return NGX_ERROR;
873
+ }
874
+
875
+ (void) ngx_cpystrn(p, name.data, name.len + 1);
876
+
877
+ name.data = p;
878
+
879
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
880
+ "upstream SSL server name: \"%s\"", name.data);
881
+
882
+ if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, name.data)
883
+ == 0)
884
+ {
885
+ ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
886
+ "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
887
+ return NGX_ERROR;
888
+ }
889
+
890
+ #endif
891
+
892
+ done:
893
+
894
+ u->ssl_name = name;
895
+
896
+ return NGX_OK;
897
+ }
898
+
899
+ #endif
900
+
901
+
902
+ static void
903
+ ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
904
+ {
905
+ ngx_stream_proxy_process_connection(ev, ev->write);
906
+ }
907
+
908
+
909
+ static void
910
+ ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
911
+ {
912
+ ngx_stream_proxy_process_connection(ev, !ev->write);
913
+ }
914
+
915
+
916
+ static void
917
+ ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
918
+ {
919
+ ngx_connection_t *c, *pc;
920
+ ngx_stream_session_t *s;
921
+ ngx_stream_upstream_t *u;
922
+ ngx_stream_proxy_srv_conf_t *pscf;
923
+
924
+ c = ev->data;
925
+ s = c->data;
926
+ u = s->upstream;
927
+
928
+ c = s->connection;
929
+ pc = u->peer.connection;
930
+
931
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
932
+
933
+ if (ev->timedout) {
934
+ ev->timedout = 0;
935
+
936
+ if (ev->delayed) {
937
+ ev->delayed = 0;
938
+
939
+ if (!ev->ready) {
940
+ if (ngx_handle_read_event(ev, 0) != NGX_OK) {
941
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
942
+ return;
943
+ }
944
+
945
+ if (u->connected && !c->read->delayed && !pc->read->delayed) {
946
+ ngx_add_timer(c->write, pscf->timeout);
947
+ }
948
+
949
+ return;
950
+ }
951
+
952
+ } else {
953
+ if (s->connection->type == SOCK_DGRAM) {
954
+ if (pscf->responses == NGX_MAX_INT32_VALUE) {
955
+
956
+ /*
957
+ * successfully terminate timed out UDP session
958
+ * with unspecified number of responses
959
+ */
960
+
961
+ pc->read->ready = 0;
962
+ pc->read->eof = 1;
963
+
964
+ ngx_stream_proxy_process(s, 1, 0);
965
+ return;
966
+ }
967
+
968
+ if (u->received == 0) {
969
+ ngx_stream_proxy_next_upstream(s);
970
+ return;
971
+ }
972
+ }
973
+
974
+ ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
975
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
976
+ return;
977
+ }
978
+
979
+ } else if (ev->delayed) {
980
+
981
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
982
+ "stream connection delayed");
983
+
984
+ if (ngx_handle_read_event(ev, 0) != NGX_OK) {
985
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
986
+ }
987
+
988
+ return;
989
+ }
990
+
991
+ if (from_upstream && !u->connected) {
992
+ return;
993
+ }
994
+
995
+ ngx_stream_proxy_process(s, from_upstream, ev->write);
996
+ }
997
+
998
+
999
+ static void
1000
+ ngx_stream_proxy_connect_handler(ngx_event_t *ev)
1001
+ {
1002
+ ngx_connection_t *c;
1003
+ ngx_stream_session_t *s;
1004
+
1005
+ c = ev->data;
1006
+ s = c->data;
1007
+
1008
+ if (ev->timedout) {
1009
+ ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
1010
+ ngx_stream_proxy_next_upstream(s);
1011
+ return;
1012
+ }
1013
+
1014
+ ngx_del_timer(c->write);
1015
+
1016
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
1017
+ "stream proxy connect upstream");
1018
+
1019
+ if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
1020
+ ngx_stream_proxy_next_upstream(s);
1021
+ return;
1022
+ }
1023
+
1024
+ ngx_stream_proxy_init_upstream(s);
1025
+ }
1026
+
1027
+
1028
+ static ngx_int_t
1029
+ ngx_stream_proxy_test_connect(ngx_connection_t *c)
1030
+ {
1031
+ int err;
1032
+ socklen_t len;
1033
+
1034
+ #if (NGX_HAVE_KQUEUE)
1035
+
1036
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1037
+ err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno;
1038
+
1039
+ if (err) {
1040
+ (void) ngx_connection_error(c, err,
1041
+ "kevent() reported that connect() failed");
1042
+ return NGX_ERROR;
1043
+ }
1044
+
1045
+ } else
1046
+ #endif
1047
+ {
1048
+ err = 0;
1049
+ len = sizeof(int);
1050
+
1051
+ /*
1052
+ * BSDs and Linux return 0 and set a pending error in err
1053
+ * Solaris returns -1 and sets errno
1054
+ */
1055
+
1056
+ if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1057
+ == -1)
1058
+ {
1059
+ err = ngx_socket_errno;
1060
+ }
1061
+
1062
+ if (err) {
1063
+ (void) ngx_connection_error(c, err, "connect() failed");
1064
+ return NGX_ERROR;
1065
+ }
1066
+ }
1067
+
1068
+ return NGX_OK;
1069
+ }
1070
+
1071
+
1072
+ static void
1073
+ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
1074
+ ngx_uint_t do_write)
1075
+ {
1076
+ off_t *received, limit;
1077
+ size_t size, limit_rate;
1078
+ ssize_t n;
1079
+ ngx_buf_t *b;
1080
+ ngx_uint_t flags;
1081
+ ngx_msec_t delay;
1082
+ ngx_connection_t *c, *pc, *src, *dst;
1083
+ ngx_log_handler_pt handler;
1084
+ ngx_stream_upstream_t *u;
1085
+ ngx_stream_proxy_srv_conf_t *pscf;
1086
+
1087
+ u = s->upstream;
1088
+
1089
+ c = s->connection;
1090
+ pc = u->connected ? u->peer.connection : NULL;
1091
+
1092
+ if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) {
1093
+
1094
+ /* socket is already closed on worker shutdown */
1095
+
1096
+ handler = c->log->handler;
1097
+ c->log->handler = NULL;
1098
+
1099
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown");
1100
+
1101
+ c->log->handler = handler;
1102
+
1103
+ ngx_stream_proxy_finalize(s, NGX_OK);
1104
+ return;
1105
+ }
1106
+
1107
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1108
+
1109
+ if (from_upstream) {
1110
+ src = pc;
1111
+ dst = c;
1112
+ b = &u->upstream_buf;
1113
+ limit_rate = pscf->download_rate;
1114
+ received = &u->received;
1115
+
1116
+ } else {
1117
+ src = c;
1118
+ dst = pc;
1119
+ b = &u->downstream_buf;
1120
+ limit_rate = pscf->upload_rate;
1121
+ received = &s->received;
1122
+ }
1123
+
1124
+ for ( ;; ) {
1125
+
1126
+ if (do_write) {
1127
+
1128
+ size = b->last - b->pos;
1129
+
1130
+ if (size && dst && dst->write->ready) {
1131
+
1132
+ n = dst->send(dst, b->pos, size);
1133
+
1134
+ if (n == NGX_AGAIN && dst->shared) {
1135
+ /* cannot wait on a shared socket */
1136
+ n = NGX_ERROR;
1137
+ }
1138
+
1139
+ if (n == NGX_ERROR) {
1140
+ if (c->type == SOCK_DGRAM && !from_upstream) {
1141
+ ngx_stream_proxy_next_upstream(s);
1142
+ return;
1143
+ }
1144
+
1145
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
1146
+ return;
1147
+ }
1148
+
1149
+ if (n > 0) {
1150
+ b->pos += n;
1151
+
1152
+ if (b->pos == b->last) {
1153
+ b->pos = b->start;
1154
+ b->last = b->start;
1155
+ }
1156
+ }
1157
+ }
1158
+ }
1159
+
1160
+ size = b->end - b->last;
1161
+
1162
+ if (size && src->read->ready && !src->read->delayed) {
1163
+
1164
+ if (limit_rate) {
1165
+ limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
1166
+ - *received;
1167
+
1168
+ if (limit <= 0) {
1169
+ src->read->delayed = 1;
1170
+ delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
1171
+ ngx_add_timer(src->read, delay);
1172
+ break;
1173
+ }
1174
+
1175
+ if ((off_t) size > limit) {
1176
+ size = (size_t) limit;
1177
+ }
1178
+ }
1179
+
1180
+ n = src->recv(src, b->last, size);
1181
+
1182
+ if (n == NGX_AGAIN || n == 0) {
1183
+ break;
1184
+ }
1185
+
1186
+ if (n > 0) {
1187
+ if (limit_rate) {
1188
+ delay = (ngx_msec_t) (n * 1000 / limit_rate);
1189
+
1190
+ if (delay > 0) {
1191
+ src->read->delayed = 1;
1192
+ ngx_add_timer(src->read, delay);
1193
+ }
1194
+ }
1195
+
1196
+ if (c->type == SOCK_DGRAM && ++u->responses == pscf->responses)
1197
+ {
1198
+ src->read->ready = 0;
1199
+ src->read->eof = 1;
1200
+ }
1201
+
1202
+ *received += n;
1203
+ b->last += n;
1204
+ do_write = 1;
1205
+
1206
+ continue;
1207
+ }
1208
+
1209
+ if (n == NGX_ERROR) {
1210
+ if (c->type == SOCK_DGRAM && u->received == 0) {
1211
+ ngx_stream_proxy_next_upstream(s);
1212
+ return;
1213
+ }
1214
+
1215
+ src->read->eof = 1;
1216
+ }
1217
+ }
1218
+
1219
+ break;
1220
+ }
1221
+
1222
+ if (src->read->eof && (b->pos == b->last || (dst && dst->read->eof))) {
1223
+ handler = c->log->handler;
1224
+ c->log->handler = NULL;
1225
+
1226
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1227
+ "%s%s disconnected"
1228
+ ", bytes from/to client:%O/%O"
1229
+ ", bytes from/to upstream:%O/%O",
1230
+ src->type == SOCK_DGRAM ? "udp " : "",
1231
+ from_upstream ? "upstream" : "client",
1232
+ s->received, c->sent, u->received, pc ? pc->sent : 0);
1233
+
1234
+ c->log->handler = handler;
1235
+
1236
+ ngx_stream_proxy_finalize(s, NGX_OK);
1237
+ return;
1238
+ }
1239
+
1240
+ flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
1241
+
1242
+ if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) {
1243
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
1244
+ return;
1245
+ }
1246
+
1247
+ if (dst) {
1248
+ if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) {
1249
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
1250
+ return;
1251
+ }
1252
+
1253
+ if (!c->read->delayed && !pc->read->delayed) {
1254
+ ngx_add_timer(c->write, pscf->timeout);
1255
+
1256
+ } else if (c->write->timer_set) {
1257
+ ngx_del_timer(c->write);
1258
+ }
1259
+ }
1260
+ }
1261
+
1262
+
1263
+ static void
1264
+ ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
1265
+ {
1266
+ ngx_msec_t timeout;
1267
+ ngx_connection_t *pc;
1268
+ ngx_stream_upstream_t *u;
1269
+ ngx_stream_proxy_srv_conf_t *pscf;
1270
+
1271
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1272
+ "stream proxy next upstream");
1273
+
1274
+ u = s->upstream;
1275
+
1276
+ if (u->peer.sockaddr) {
1277
+ u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
1278
+ u->peer.sockaddr = NULL;
1279
+ }
1280
+
1281
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1282
+
1283
+ timeout = pscf->next_upstream_timeout;
1284
+
1285
+ if (u->peer.tries == 0
1286
+ || !pscf->next_upstream
1287
+ || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
1288
+ {
1289
+ ngx_stream_proxy_finalize(s, NGX_DECLINED);
1290
+ return;
1291
+ }
1292
+
1293
+ pc = u->peer.connection;
1294
+
1295
+ if (pc) {
1296
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1297
+ "close proxy upstream connection: %d", pc->fd);
1298
+
1299
+ #if (NGX_STREAM_SSL)
1300
+ if (pc->ssl) {
1301
+ pc->ssl->no_wait_shutdown = 1;
1302
+ pc->ssl->no_send_shutdown = 1;
1303
+
1304
+ (void) ngx_ssl_shutdown(pc);
1305
+ }
1306
+ #endif
1307
+
1308
+ ngx_close_connection(pc);
1309
+ u->peer.connection = NULL;
1310
+ }
1311
+
1312
+ ngx_stream_proxy_connect(s);
1313
+ }
1314
+
1315
+
1316
+ static void
1317
+ ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc)
1318
+ {
1319
+ ngx_connection_t *pc;
1320
+ ngx_stream_upstream_t *u;
1321
+
1322
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1323
+ "finalize stream proxy: %i", rc);
1324
+
1325
+ u = s->upstream;
1326
+
1327
+ if (u == NULL) {
1328
+ goto noupstream;
1329
+ }
1330
+
1331
+ if (u->peer.free && u->peer.sockaddr) {
1332
+ u->peer.free(&u->peer, u->peer.data, 0);
1333
+ u->peer.sockaddr = NULL;
1334
+ }
1335
+
1336
+ pc = u->peer.connection;
1337
+
1338
+ if (pc) {
1339
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1340
+ "close stream proxy upstream connection: %d", pc->fd);
1341
+
1342
+ #if (NGX_STREAM_SSL)
1343
+ if (pc->ssl) {
1344
+ pc->ssl->no_wait_shutdown = 1;
1345
+ (void) ngx_ssl_shutdown(pc);
1346
+ }
1347
+ #endif
1348
+
1349
+ ngx_close_connection(pc);
1350
+ u->peer.connection = NULL;
1351
+ }
1352
+
1353
+ noupstream:
1354
+
1355
+ ngx_stream_close_connection(s->connection);
1356
+ }
1357
+
1358
+
1359
+ static u_char *
1360
+ ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
1361
+ {
1362
+ u_char *p;
1363
+ ngx_connection_t *pc;
1364
+ ngx_stream_session_t *s;
1365
+ ngx_stream_upstream_t *u;
1366
+
1367
+ s = log->data;
1368
+
1369
+ u = s->upstream;
1370
+
1371
+ p = buf;
1372
+
1373
+ if (u->peer.name) {
1374
+ p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
1375
+ len -= p - buf;
1376
+ }
1377
+
1378
+ pc = u->peer.connection;
1379
+
1380
+ p = ngx_snprintf(p, len,
1381
+ ", bytes from/to client:%O/%O"
1382
+ ", bytes from/to upstream:%O/%O",
1383
+ s->received, s->connection->sent,
1384
+ u->received, pc ? pc->sent : 0);
1385
+
1386
+ return p;
1387
+ }
1388
+
1389
+
1390
+ static void *
1391
+ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
1392
+ {
1393
+ ngx_stream_proxy_srv_conf_t *conf;
1394
+
1395
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
1396
+ if (conf == NULL) {
1397
+ return NULL;
1398
+ }
1399
+
1400
+ /*
1401
+ * set by ngx_pcalloc():
1402
+ *
1403
+ * conf->ssl_protocols = 0;
1404
+ * conf->ssl_ciphers = { 0, NULL };
1405
+ * conf->ssl_name = { 0, NULL };
1406
+ * conf->ssl_trusted_certificate = { 0, NULL };
1407
+ * conf->ssl_crl = { 0, NULL };
1408
+ * conf->ssl_certificate = { 0, NULL };
1409
+ * conf->ssl_certificate_key = { 0, NULL };
1410
+ *
1411
+ * conf->ssl = NULL;
1412
+ * conf->upstream = NULL;
1413
+ */
1414
+
1415
+ conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1416
+ conf->timeout = NGX_CONF_UNSET_MSEC;
1417
+ conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
1418
+ conf->buffer_size = NGX_CONF_UNSET_SIZE;
1419
+ conf->upload_rate = NGX_CONF_UNSET_SIZE;
1420
+ conf->download_rate = NGX_CONF_UNSET_SIZE;
1421
+ conf->responses = NGX_CONF_UNSET_UINT;
1422
+ conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
1423
+ conf->next_upstream = NGX_CONF_UNSET;
1424
+ conf->proxy_protocol = NGX_CONF_UNSET;
1425
+ conf->local = NGX_CONF_UNSET_PTR;
1426
+
1427
+ #if (NGX_STREAM_SSL)
1428
+ conf->ssl_enable = NGX_CONF_UNSET;
1429
+ conf->ssl_session_reuse = NGX_CONF_UNSET;
1430
+ conf->ssl_server_name = NGX_CONF_UNSET;
1431
+ conf->ssl_verify = NGX_CONF_UNSET;
1432
+ conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
1433
+ conf->ssl_passwords = NGX_CONF_UNSET_PTR;
1434
+ #endif
1435
+
1436
+ return conf;
1437
+ }
1438
+
1439
+
1440
+ static char *
1441
+ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
1442
+ {
1443
+ ngx_stream_proxy_srv_conf_t *prev = parent;
1444
+ ngx_stream_proxy_srv_conf_t *conf = child;
1445
+
1446
+ ngx_conf_merge_msec_value(conf->connect_timeout,
1447
+ prev->connect_timeout, 60000);
1448
+
1449
+ ngx_conf_merge_msec_value(conf->timeout,
1450
+ prev->timeout, 10 * 60000);
1451
+
1452
+ ngx_conf_merge_msec_value(conf->next_upstream_timeout,
1453
+ prev->next_upstream_timeout, 0);
1454
+
1455
+ ngx_conf_merge_size_value(conf->buffer_size,
1456
+ prev->buffer_size, 16384);
1457
+
1458
+ ngx_conf_merge_size_value(conf->upload_rate,
1459
+ prev->upload_rate, 0);
1460
+
1461
+ ngx_conf_merge_size_value(conf->download_rate,
1462
+ prev->download_rate, 0);
1463
+
1464
+ ngx_conf_merge_uint_value(conf->responses,
1465
+ prev->responses, NGX_MAX_INT32_VALUE);
1466
+
1467
+ ngx_conf_merge_uint_value(conf->next_upstream_tries,
1468
+ prev->next_upstream_tries, 0);
1469
+
1470
+ ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1);
1471
+
1472
+ ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
1473
+
1474
+ ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);
1475
+
1476
+ #if (NGX_STREAM_SSL)
1477
+
1478
+ ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
1479
+
1480
+ ngx_conf_merge_value(conf->ssl_session_reuse,
1481
+ prev->ssl_session_reuse, 1);
1482
+
1483
+ ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
1484
+ (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
1485
+ |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
1486
+
1487
+ ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
1488
+
1489
+ ngx_conf_merge_str_value(conf->ssl_name, prev->ssl_name, "");
1490
+
1491
+ ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
1492
+
1493
+ ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0);
1494
+
1495
+ ngx_conf_merge_uint_value(conf->ssl_verify_depth,
1496
+ prev->ssl_verify_depth, 1);
1497
+
1498
+ ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
1499
+ prev->ssl_trusted_certificate, "");
1500
+
1501
+ ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
1502
+
1503
+ ngx_conf_merge_str_value(conf->ssl_certificate,
1504
+ prev->ssl_certificate, "");
1505
+
1506
+ ngx_conf_merge_str_value(conf->ssl_certificate_key,
1507
+ prev->ssl_certificate_key, "");
1508
+
1509
+ ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
1510
+
1511
+ if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
1512
+ return NGX_CONF_ERROR;
1513
+ }
1514
+
1515
+ #endif
1516
+
1517
+ return NGX_CONF_OK;
1518
+ }
1519
+
1520
+
1521
+ #if (NGX_STREAM_SSL)
1522
+
1523
+ static ngx_int_t
1524
+ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
1525
+ {
1526
+ ngx_pool_cleanup_t *cln;
1527
+
1528
+ pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
1529
+ if (pscf->ssl == NULL) {
1530
+ return NGX_ERROR;
1531
+ }
1532
+
1533
+ pscf->ssl->log = cf->log;
1534
+
1535
+ if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
1536
+ return NGX_ERROR;
1537
+ }
1538
+
1539
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
1540
+ if (cln == NULL) {
1541
+ return NGX_ERROR;
1542
+ }
1543
+
1544
+ cln->handler = ngx_ssl_cleanup_ctx;
1545
+ cln->data = pscf->ssl;
1546
+
1547
+ if (pscf->ssl_certificate.len) {
1548
+
1549
+ if (pscf->ssl_certificate_key.len == 0) {
1550
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1551
+ "no \"proxy_ssl_certificate_key\" is defined "
1552
+ "for certificate \"%V\"", &pscf->ssl_certificate);
1553
+ return NGX_ERROR;
1554
+ }
1555
+
1556
+ if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate,
1557
+ &pscf->ssl_certificate_key, pscf->ssl_passwords)
1558
+ != NGX_OK)
1559
+ {
1560
+ return NGX_ERROR;
1561
+ }
1562
+ }
1563
+
1564
+ if (SSL_CTX_set_cipher_list(pscf->ssl->ctx,
1565
+ (const char *) pscf->ssl_ciphers.data)
1566
+ == 0)
1567
+ {
1568
+ ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
1569
+ "SSL_CTX_set_cipher_list(\"%V\") failed",
1570
+ &pscf->ssl_ciphers);
1571
+ return NGX_ERROR;
1572
+ }
1573
+
1574
+ if (pscf->ssl_verify) {
1575
+ if (pscf->ssl_trusted_certificate.len == 0) {
1576
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1577
+ "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
1578
+ return NGX_ERROR;
1579
+ }
1580
+
1581
+ if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
1582
+ &pscf->ssl_trusted_certificate,
1583
+ pscf->ssl_verify_depth)
1584
+ != NGX_OK)
1585
+ {
1586
+ return NGX_ERROR;
1587
+ }
1588
+
1589
+ if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
1590
+ return NGX_ERROR;
1591
+ }
1592
+ }
1593
+
1594
+ return NGX_OK;
1595
+ }
1596
+
1597
+ #endif
1598
+
1599
+
1600
+ static char *
1601
+ ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1602
+ {
1603
+ ngx_stream_proxy_srv_conf_t *pscf = conf;
1604
+
1605
+ ngx_url_t u;
1606
+ ngx_str_t *value, *url;
1607
+ ngx_stream_core_srv_conf_t *cscf;
1608
+
1609
+ if (pscf->upstream) {
1610
+ return "is duplicate";
1611
+ }
1612
+
1613
+ cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
1614
+
1615
+ cscf->handler = ngx_stream_proxy_handler;
1616
+
1617
+ value = cf->args->elts;
1618
+
1619
+ url = &value[1];
1620
+
1621
+ ngx_memzero(&u, sizeof(ngx_url_t));
1622
+
1623
+ u.url = *url;
1624
+ u.no_resolve = 1;
1625
+
1626
+ pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
1627
+ if (pscf->upstream == NULL) {
1628
+ return NGX_CONF_ERROR;
1629
+ }
1630
+
1631
+ return NGX_CONF_OK;
1632
+ }
1633
+
1634
+
1635
+ static char *
1636
+ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1637
+ {
1638
+ ngx_stream_proxy_srv_conf_t *pscf = conf;
1639
+
1640
+ ngx_int_t rc;
1641
+ ngx_str_t *value;
1642
+
1643
+ if (pscf->local != NGX_CONF_UNSET_PTR) {
1644
+ return "is duplicate";
1645
+ }
1646
+
1647
+ value = cf->args->elts;
1648
+
1649
+ if (ngx_strcmp(value[1].data, "off") == 0) {
1650
+ pscf->local = NULL;
1651
+ return NGX_CONF_OK;
1652
+ }
1653
+
1654
+ pscf->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
1655
+ if (pscf->local == NULL) {
1656
+ return NGX_CONF_ERROR;
1657
+ }
1658
+
1659
+ rc = ngx_parse_addr(cf->pool, pscf->local, value[1].data, value[1].len);
1660
+
1661
+ switch (rc) {
1662
+ case NGX_OK:
1663
+ pscf->local->name = value[1];
1664
+ return NGX_CONF_OK;
1665
+
1666
+ case NGX_DECLINED:
1667
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1668
+ "invalid address \"%V\"", &value[1]);
1669
+ /* fall through */
1670
+
1671
+ default:
1672
+ return NGX_CONF_ERROR;
1673
+ }
1674
+ }