nginxtra 1.0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (363) hide show
  1. data/VERSION +1 -0
  2. data/bin/nginxtra +5 -0
  3. data/lib/nginxtra.rb +12 -0
  4. data/lib/nginxtra/action.rb +36 -0
  5. data/lib/nginxtra/actions/compile.rb +60 -0
  6. data/lib/nginxtra/actions/install.rb +99 -0
  7. data/lib/nginxtra/actions/reload.rb +14 -0
  8. data/lib/nginxtra/actions/restart.rb +15 -0
  9. data/lib/nginxtra/actions/start.rb +53 -0
  10. data/lib/nginxtra/actions/status.rb +31 -0
  11. data/lib/nginxtra/actions/stop.rb +14 -0
  12. data/lib/nginxtra/cli.rb +77 -0
  13. data/lib/nginxtra/config.rb +339 -0
  14. data/lib/nginxtra/error.rb +13 -0
  15. data/lib/nginxtra/status.rb +57 -0
  16. data/src/nginx/CHANGES +5630 -0
  17. data/src/nginx/CHANGES.ru +5716 -0
  18. data/src/nginx/LICENSE +25 -0
  19. data/src/nginx/README +3 -0
  20. data/src/nginx/auto/cc/acc +15 -0
  21. data/src/nginx/auto/cc/bcc +72 -0
  22. data/src/nginx/auto/cc/ccc +46 -0
  23. data/src/nginx/auto/cc/conf +189 -0
  24. data/src/nginx/auto/cc/gcc +183 -0
  25. data/src/nginx/auto/cc/icc +121 -0
  26. data/src/nginx/auto/cc/msvc +138 -0
  27. data/src/nginx/auto/cc/name +101 -0
  28. data/src/nginx/auto/cc/owc +104 -0
  29. data/src/nginx/auto/cc/sunc +158 -0
  30. data/src/nginx/auto/define +12 -0
  31. data/src/nginx/auto/endianess +45 -0
  32. data/src/nginx/auto/feature +123 -0
  33. data/src/nginx/auto/have +12 -0
  34. data/src/nginx/auto/have_headers +12 -0
  35. data/src/nginx/auto/headers +13 -0
  36. data/src/nginx/auto/include +61 -0
  37. data/src/nginx/auto/init +51 -0
  38. data/src/nginx/auto/install +184 -0
  39. data/src/nginx/auto/lib/conf +83 -0
  40. data/src/nginx/auto/lib/geoip/conf +79 -0
  41. data/src/nginx/auto/lib/google-perftools/conf +45 -0
  42. data/src/nginx/auto/lib/libatomic/conf +43 -0
  43. data/src/nginx/auto/lib/libatomic/make +14 -0
  44. data/src/nginx/auto/lib/libgd/conf +83 -0
  45. data/src/nginx/auto/lib/libxslt/conf +156 -0
  46. data/src/nginx/auto/lib/make +32 -0
  47. data/src/nginx/auto/lib/md5/conf +103 -0
  48. data/src/nginx/auto/lib/md5/make +96 -0
  49. data/src/nginx/auto/lib/md5/makefile.bcc +22 -0
  50. data/src/nginx/auto/lib/md5/makefile.msvc +22 -0
  51. data/src/nginx/auto/lib/md5/makefile.owc +11 -0
  52. data/src/nginx/auto/lib/openssl/conf +74 -0
  53. data/src/nginx/auto/lib/openssl/make +67 -0
  54. data/src/nginx/auto/lib/openssl/makefile.bcc +18 -0
  55. data/src/nginx/auto/lib/openssl/makefile.msvc +14 -0
  56. data/src/nginx/auto/lib/pcre/conf +180 -0
  57. data/src/nginx/auto/lib/pcre/make +64 -0
  58. data/src/nginx/auto/lib/pcre/makefile.bcc +26 -0
  59. data/src/nginx/auto/lib/pcre/makefile.msvc +22 -0
  60. data/src/nginx/auto/lib/pcre/makefile.owc +24 -0
  61. data/src/nginx/auto/lib/perl/conf +60 -0
  62. data/src/nginx/auto/lib/perl/make +36 -0
  63. data/src/nginx/auto/lib/sha1/conf +79 -0
  64. data/src/nginx/auto/lib/sha1/make +96 -0
  65. data/src/nginx/auto/lib/sha1/makefile.bcc +22 -0
  66. data/src/nginx/auto/lib/sha1/makefile.msvc +22 -0
  67. data/src/nginx/auto/lib/sha1/makefile.owc +11 -0
  68. data/src/nginx/auto/lib/test +40 -0
  69. data/src/nginx/auto/lib/zlib/conf +76 -0
  70. data/src/nginx/auto/lib/zlib/make +114 -0
  71. data/src/nginx/auto/lib/zlib/makefile.bcc +15 -0
  72. data/src/nginx/auto/lib/zlib/makefile.msvc +14 -0
  73. data/src/nginx/auto/lib/zlib/makefile.owc +14 -0
  74. data/src/nginx/auto/lib/zlib/patch.zlib.h +10 -0
  75. data/src/nginx/auto/make +417 -0
  76. data/src/nginx/auto/modules +479 -0
  77. data/src/nginx/auto/nohave +12 -0
  78. data/src/nginx/auto/options +490 -0
  79. data/src/nginx/auto/os/conf +105 -0
  80. data/src/nginx/auto/os/darwin +116 -0
  81. data/src/nginx/auto/os/freebsd +136 -0
  82. data/src/nginx/auto/os/linux +152 -0
  83. data/src/nginx/auto/os/solaris +60 -0
  84. data/src/nginx/auto/os/win32 +29 -0
  85. data/src/nginx/auto/sources +518 -0
  86. data/src/nginx/auto/stubs +8 -0
  87. data/src/nginx/auto/summary +114 -0
  88. data/src/nginx/auto/types/sizeof +83 -0
  89. data/src/nginx/auto/types/typedef +77 -0
  90. data/src/nginx/auto/types/uintptr_t +42 -0
  91. data/src/nginx/auto/types/value +12 -0
  92. data/src/nginx/auto/unix +719 -0
  93. data/src/nginx/conf/fastcgi.conf +24 -0
  94. data/src/nginx/conf/fastcgi_params +23 -0
  95. data/src/nginx/conf/koi-utf +109 -0
  96. data/src/nginx/conf/koi-win +103 -0
  97. data/src/nginx/conf/mime.types +80 -0
  98. data/src/nginx/conf/nginx.conf +118 -0
  99. data/src/nginx/conf/scgi_params +15 -0
  100. data/src/nginx/conf/uwsgi_params +15 -0
  101. data/src/nginx/conf/win-utf +126 -0
  102. data/src/nginx/configure +108 -0
  103. data/src/nginx/contrib/README +15 -0
  104. data/src/nginx/contrib/geo2nginx.pl +58 -0
  105. data/src/nginx/contrib/unicode2nginx/koi-utf +131 -0
  106. data/src/nginx/contrib/unicode2nginx/unicode-to-nginx.pl +45 -0
  107. data/src/nginx/contrib/unicode2nginx/win-utf +130 -0
  108. data/src/nginx/html/50x.html +18 -0
  109. data/src/nginx/html/index.html +8 -0
  110. data/src/nginx/man/nginx.8 +202 -0
  111. data/src/nginx/src/core/nginx.c +1333 -0
  112. data/src/nginx/src/core/nginx.h +20 -0
  113. data/src/nginx/src/core/ngx_array.c +147 -0
  114. data/src/nginx/src/core/ngx_array.h +53 -0
  115. data/src/nginx/src/core/ngx_buf.c +218 -0
  116. data/src/nginx/src/core/ngx_buf.h +162 -0
  117. data/src/nginx/src/core/ngx_conf_file.c +1506 -0
  118. data/src/nginx/src/core/ngx_conf_file.h +348 -0
  119. data/src/nginx/src/core/ngx_config.h +134 -0
  120. data/src/nginx/src/core/ngx_connection.c +1074 -0
  121. data/src/nginx/src/core/ngx_connection.h +195 -0
  122. data/src/nginx/src/core/ngx_core.h +95 -0
  123. data/src/nginx/src/core/ngx_cpuinfo.c +139 -0
  124. data/src/nginx/src/core/ngx_crc.h +39 -0
  125. data/src/nginx/src/core/ngx_crc32.c +129 -0
  126. data/src/nginx/src/core/ngx_crc32.h +79 -0
  127. data/src/nginx/src/core/ngx_crypt.c +238 -0
  128. data/src/nginx/src/core/ngx_crypt.h +20 -0
  129. data/src/nginx/src/core/ngx_cycle.c +1379 -0
  130. data/src/nginx/src/core/ngx_cycle.h +142 -0
  131. data/src/nginx/src/core/ngx_file.c +993 -0
  132. data/src/nginx/src/core/ngx_file.h +151 -0
  133. data/src/nginx/src/core/ngx_hash.c +976 -0
  134. data/src/nginx/src/core/ngx_hash.h +122 -0
  135. data/src/nginx/src/core/ngx_inet.c +1008 -0
  136. data/src/nginx/src/core/ngx_inet.h +120 -0
  137. data/src/nginx/src/core/ngx_list.c +71 -0
  138. data/src/nginx/src/core/ngx_list.h +83 -0
  139. data/src/nginx/src/core/ngx_log.c +459 -0
  140. data/src/nginx/src/core/ngx_log.h +250 -0
  141. data/src/nginx/src/core/ngx_md5.c +289 -0
  142. data/src/nginx/src/core/ngx_md5.h +60 -0
  143. data/src/nginx/src/core/ngx_murmurhash.c +50 -0
  144. data/src/nginx/src/core/ngx_murmurhash.h +19 -0
  145. data/src/nginx/src/core/ngx_open_file_cache.c +882 -0
  146. data/src/nginx/src/core/ngx_open_file_cache.h +119 -0
  147. data/src/nginx/src/core/ngx_output_chain.c +673 -0
  148. data/src/nginx/src/core/ngx_palloc.c +433 -0
  149. data/src/nginx/src/core/ngx_palloc.h +95 -0
  150. data/src/nginx/src/core/ngx_parse.c +249 -0
  151. data/src/nginx/src/core/ngx_parse.h +24 -0
  152. data/src/nginx/src/core/ngx_queue.c +80 -0
  153. data/src/nginx/src/core/ngx_queue.h +112 -0
  154. data/src/nginx/src/core/ngx_radix_tree.c +291 -0
  155. data/src/nginx/src/core/ngx_radix_tree.h +46 -0
  156. data/src/nginx/src/core/ngx_rbtree.c +383 -0
  157. data/src/nginx/src/core/ngx_rbtree.h +84 -0
  158. data/src/nginx/src/core/ngx_regex.c +206 -0
  159. data/src/nginx/src/core/ngx_regex.h +56 -0
  160. data/src/nginx/src/core/ngx_resolver.c +2201 -0
  161. data/src/nginx/src/core/ngx_resolver.h +149 -0
  162. data/src/nginx/src/core/ngx_sha1.h +31 -0
  163. data/src/nginx/src/core/ngx_shmtx.c +284 -0
  164. data/src/nginx/src/core/ngx_shmtx.h +38 -0
  165. data/src/nginx/src/core/ngx_slab.c +701 -0
  166. data/src/nginx/src/core/ngx_slab.h +54 -0
  167. data/src/nginx/src/core/ngx_spinlock.c +53 -0
  168. data/src/nginx/src/core/ngx_string.c +1837 -0
  169. data/src/nginx/src/core/ngx_string.h +231 -0
  170. data/src/nginx/src/core/ngx_times.c +407 -0
  171. data/src/nginx/src/core/ngx_times.h +51 -0
  172. data/src/nginx/src/event/modules/ngx_aio_module.c +171 -0
  173. data/src/nginx/src/event/modules/ngx_devpoll_module.c +569 -0
  174. data/src/nginx/src/event/modules/ngx_epoll_module.c +833 -0
  175. data/src/nginx/src/event/modules/ngx_eventport_module.c +602 -0
  176. data/src/nginx/src/event/modules/ngx_kqueue_module.c +785 -0
  177. data/src/nginx/src/event/modules/ngx_poll_module.c +443 -0
  178. data/src/nginx/src/event/modules/ngx_rtsig_module.c +735 -0
  179. data/src/nginx/src/event/modules/ngx_select_module.c +435 -0
  180. data/src/nginx/src/event/modules/ngx_win32_select_module.c +400 -0
  181. data/src/nginx/src/event/ngx_event.c +1275 -0
  182. data/src/nginx/src/event/ngx_event.h +573 -0
  183. data/src/nginx/src/event/ngx_event_accept.c +428 -0
  184. data/src/nginx/src/event/ngx_event_busy_lock.c +286 -0
  185. data/src/nginx/src/event/ngx_event_busy_lock.h +65 -0
  186. data/src/nginx/src/event/ngx_event_connect.c +258 -0
  187. data/src/nginx/src/event/ngx_event_connect.h +76 -0
  188. data/src/nginx/src/event/ngx_event_mutex.c +70 -0
  189. data/src/nginx/src/event/ngx_event_openssl.c +2382 -0
  190. data/src/nginx/src/event/ngx_event_openssl.h +162 -0
  191. data/src/nginx/src/event/ngx_event_pipe.c +996 -0
  192. data/src/nginx/src/event/ngx_event_pipe.h +95 -0
  193. data/src/nginx/src/event/ngx_event_posted.c +173 -0
  194. data/src/nginx/src/event/ngx_event_posted.h +75 -0
  195. data/src/nginx/src/event/ngx_event_timer.c +159 -0
  196. data/src/nginx/src/event/ngx_event_timer.h +102 -0
  197. data/src/nginx/src/http/modules/ngx_http_access_module.c +384 -0
  198. data/src/nginx/src/http/modules/ngx_http_addition_filter_module.c +250 -0
  199. data/src/nginx/src/http/modules/ngx_http_auth_basic_module.c +478 -0
  200. data/src/nginx/src/http/modules/ngx_http_autoindex_module.c +701 -0
  201. data/src/nginx/src/http/modules/ngx_http_browser_module.c +713 -0
  202. data/src/nginx/src/http/modules/ngx_http_charset_filter_module.c +1681 -0
  203. data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +242 -0
  204. data/src/nginx/src/http/modules/ngx_http_dav_module.c +1141 -0
  205. data/src/nginx/src/http/modules/ngx_http_degradation_module.c +243 -0
  206. data/src/nginx/src/http/modules/ngx_http_empty_gif_module.c +140 -0
  207. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +2916 -0
  208. data/src/nginx/src/http/modules/ngx_http_flv_module.c +254 -0
  209. data/src/nginx/src/http/modules/ngx_http_geo_module.c +1441 -0
  210. data/src/nginx/src/http/modules/ngx_http_geoip_module.c +671 -0
  211. data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +1206 -0
  212. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +299 -0
  213. data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +616 -0
  214. data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1489 -0
  215. data/src/nginx/src/http/modules/ngx_http_index_module.c +516 -0
  216. data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +809 -0
  217. data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +553 -0
  218. data/src/nginx/src/http/modules/ngx_http_log_module.c +1357 -0
  219. data/src/nginx/src/http/modules/ngx_http_map_module.c +575 -0
  220. data/src/nginx/src/http/modules/ngx_http_memcached_module.c +624 -0
  221. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +3000 -0
  222. data/src/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +143 -0
  223. data/src/nginx/src/http/modules/ngx_http_proxy_module.c +2831 -0
  224. data/src/nginx/src/http/modules/ngx_http_random_index_module.c +317 -0
  225. data/src/nginx/src/http/modules/ngx_http_range_filter_module.c +855 -0
  226. data/src/nginx/src/http/modules/ngx_http_realip_module.c +476 -0
  227. data/src/nginx/src/http/modules/ngx_http_referer_module.c +613 -0
  228. data/src/nginx/src/http/modules/ngx_http_rewrite_module.c +1019 -0
  229. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +1714 -0
  230. data/src/nginx/src/http/modules/ngx_http_secure_link_module.c +355 -0
  231. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +242 -0
  232. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +2913 -0
  233. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.h +114 -0
  234. data/src/nginx/src/http/modules/ngx_http_ssl_module.c +652 -0
  235. data/src/nginx/src/http/modules/ngx_http_ssl_module.h +52 -0
  236. data/src/nginx/src/http/modules/ngx_http_static_module.c +278 -0
  237. data/src/nginx/src/http/modules/ngx_http_stub_status_module.c +144 -0
  238. data/src/nginx/src/http/modules/ngx_http_sub_filter_module.c +716 -0
  239. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +237 -0
  240. data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +846 -0
  241. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +1774 -0
  242. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +984 -0
  243. data/src/nginx/src/http/modules/perl/Makefile.PL +42 -0
  244. data/src/nginx/src/http/modules/perl/nginx.pm +137 -0
  245. data/src/nginx/src/http/modules/perl/nginx.xs +986 -0
  246. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.c +1076 -0
  247. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.h +67 -0
  248. data/src/nginx/src/http/modules/perl/typemap +3 -0
  249. data/src/nginx/src/http/ngx_http.c +2073 -0
  250. data/src/nginx/src/http/ngx_http.h +160 -0
  251. data/src/nginx/src/http/ngx_http_busy_lock.c +307 -0
  252. data/src/nginx/src/http/ngx_http_busy_lock.h +54 -0
  253. data/src/nginx/src/http/ngx_http_cache.h +148 -0
  254. data/src/nginx/src/http/ngx_http_config.h +75 -0
  255. data/src/nginx/src/http/ngx_http_copy_filter_module.c +300 -0
  256. data/src/nginx/src/http/ngx_http_core_module.c +4736 -0
  257. data/src/nginx/src/http/ngx_http_core_module.h +541 -0
  258. data/src/nginx/src/http/ngx_http_file_cache.c +1715 -0
  259. data/src/nginx/src/http/ngx_http_header_filter_module.c +623 -0
  260. data/src/nginx/src/http/ngx_http_parse.c +1734 -0
  261. data/src/nginx/src/http/ngx_http_parse_time.c +276 -0
  262. data/src/nginx/src/http/ngx_http_postpone_filter_module.c +178 -0
  263. data/src/nginx/src/http/ngx_http_request.c +3181 -0
  264. data/src/nginx/src/http/ngx_http_request.h +573 -0
  265. data/src/nginx/src/http/ngx_http_request_body.c +644 -0
  266. data/src/nginx/src/http/ngx_http_script.c +1752 -0
  267. data/src/nginx/src/http/ngx_http_script.h +257 -0
  268. data/src/nginx/src/http/ngx_http_special_response.c +789 -0
  269. data/src/nginx/src/http/ngx_http_upstream.c +4555 -0
  270. data/src/nginx/src/http/ngx_http_upstream.h +350 -0
  271. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +791 -0
  272. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +85 -0
  273. data/src/nginx/src/http/ngx_http_variables.c +2053 -0
  274. data/src/nginx/src/http/ngx_http_variables.h +115 -0
  275. data/src/nginx/src/http/ngx_http_write_filter_module.c +315 -0
  276. data/src/nginx/src/mail/ngx_mail.c +542 -0
  277. data/src/nginx/src/mail/ngx_mail.h +407 -0
  278. data/src/nginx/src/mail/ngx_mail_auth_http_module.c +1452 -0
  279. data/src/nginx/src/mail/ngx_mail_core_module.c +553 -0
  280. data/src/nginx/src/mail/ngx_mail_handler.c +773 -0
  281. data/src/nginx/src/mail/ngx_mail_imap_handler.c +457 -0
  282. data/src/nginx/src/mail/ngx_mail_imap_module.c +253 -0
  283. data/src/nginx/src/mail/ngx_mail_imap_module.h +39 -0
  284. data/src/nginx/src/mail/ngx_mail_parse.c +885 -0
  285. data/src/nginx/src/mail/ngx_mail_pop3_handler.c +500 -0
  286. data/src/nginx/src/mail/ngx_mail_pop3_module.c +264 -0
  287. data/src/nginx/src/mail/ngx_mail_pop3_module.h +38 -0
  288. data/src/nginx/src/mail/ngx_mail_proxy_module.c +1089 -0
  289. data/src/nginx/src/mail/ngx_mail_smtp_handler.c +872 -0
  290. data/src/nginx/src/mail/ngx_mail_smtp_module.c +308 -0
  291. data/src/nginx/src/mail/ngx_mail_smtp_module.h +45 -0
  292. data/src/nginx/src/mail/ngx_mail_ssl_module.c +491 -0
  293. data/src/nginx/src/mail/ngx_mail_ssl_module.h +52 -0
  294. data/src/nginx/src/misc/ngx_cpp_test_module.cpp +27 -0
  295. data/src/nginx/src/misc/ngx_google_perftools_module.c +126 -0
  296. data/src/nginx/src/os/unix/ngx_aio_read.c +109 -0
  297. data/src/nginx/src/os/unix/ngx_aio_read_chain.c +78 -0
  298. data/src/nginx/src/os/unix/ngx_aio_write.c +109 -0
  299. data/src/nginx/src/os/unix/ngx_aio_write_chain.c +100 -0
  300. data/src/nginx/src/os/unix/ngx_alloc.c +90 -0
  301. data/src/nginx/src/os/unix/ngx_alloc.h +45 -0
  302. data/src/nginx/src/os/unix/ngx_atomic.h +311 -0
  303. data/src/nginx/src/os/unix/ngx_channel.c +258 -0
  304. data/src/nginx/src/os/unix/ngx_channel.h +34 -0
  305. data/src/nginx/src/os/unix/ngx_daemon.c +69 -0
  306. data/src/nginx/src/os/unix/ngx_darwin.h +20 -0
  307. data/src/nginx/src/os/unix/ngx_darwin_config.h +96 -0
  308. data/src/nginx/src/os/unix/ngx_darwin_init.c +166 -0
  309. data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +366 -0
  310. data/src/nginx/src/os/unix/ngx_errno.c +87 -0
  311. data/src/nginx/src/os/unix/ngx_errno.h +68 -0
  312. data/src/nginx/src/os/unix/ngx_file_aio_read.c +208 -0
  313. data/src/nginx/src/os/unix/ngx_files.c +566 -0
  314. data/src/nginx/src/os/unix/ngx_files.h +343 -0
  315. data/src/nginx/src/os/unix/ngx_freebsd.h +24 -0
  316. data/src/nginx/src/os/unix/ngx_freebsd_config.h +119 -0
  317. data/src/nginx/src/os/unix/ngx_freebsd_init.c +259 -0
  318. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +756 -0
  319. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +122 -0
  320. data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +436 -0
  321. data/src/nginx/src/os/unix/ngx_gcc_atomic_amd64.h +82 -0
  322. data/src/nginx/src/os/unix/ngx_gcc_atomic_ppc.h +155 -0
  323. data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +82 -0
  324. data/src/nginx/src/os/unix/ngx_gcc_atomic_x86.h +127 -0
  325. data/src/nginx/src/os/unix/ngx_linux.h +18 -0
  326. data/src/nginx/src/os/unix/ngx_linux_aio_read.c +137 -0
  327. data/src/nginx/src/os/unix/ngx_linux_config.h +117 -0
  328. data/src/nginx/src/os/unix/ngx_linux_init.c +91 -0
  329. data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +378 -0
  330. data/src/nginx/src/os/unix/ngx_os.h +84 -0
  331. data/src/nginx/src/os/unix/ngx_posix_config.h +153 -0
  332. data/src/nginx/src/os/unix/ngx_posix_init.c +124 -0
  333. data/src/nginx/src/os/unix/ngx_process.c +590 -0
  334. data/src/nginx/src/os/unix/ngx_process.h +87 -0
  335. data/src/nginx/src/os/unix/ngx_process_cycle.c +1390 -0
  336. data/src/nginx/src/os/unix/ngx_process_cycle.h +61 -0
  337. data/src/nginx/src/os/unix/ngx_pthread_thread.c +278 -0
  338. data/src/nginx/src/os/unix/ngx_readv_chain.c +258 -0
  339. data/src/nginx/src/os/unix/ngx_recv.c +180 -0
  340. data/src/nginx/src/os/unix/ngx_send.c +73 -0
  341. data/src/nginx/src/os/unix/ngx_setproctitle.c +135 -0
  342. data/src/nginx/src/os/unix/ngx_setproctitle.h +52 -0
  343. data/src/nginx/src/os/unix/ngx_shmem.c +126 -0
  344. data/src/nginx/src/os/unix/ngx_shmem.h +29 -0
  345. data/src/nginx/src/os/unix/ngx_socket.c +116 -0
  346. data/src/nginx/src/os/unix/ngx_socket.h +64 -0
  347. data/src/nginx/src/os/unix/ngx_solaris.h +16 -0
  348. data/src/nginx/src/os/unix/ngx_solaris_config.h +107 -0
  349. data/src/nginx/src/os/unix/ngx_solaris_init.c +75 -0
  350. data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +251 -0
  351. data/src/nginx/src/os/unix/ngx_sunpro_amd64.il +43 -0
  352. data/src/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h +61 -0
  353. data/src/nginx/src/os/unix/ngx_sunpro_sparc64.il +36 -0
  354. data/src/nginx/src/os/unix/ngx_sunpro_x86.il +44 -0
  355. data/src/nginx/src/os/unix/ngx_thread.h +128 -0
  356. data/src/nginx/src/os/unix/ngx_time.c +104 -0
  357. data/src/nginx/src/os/unix/ngx_time.h +66 -0
  358. data/src/nginx/src/os/unix/ngx_udp_recv.c +115 -0
  359. data/src/nginx/src/os/unix/ngx_user.c +109 -0
  360. data/src/nginx/src/os/unix/ngx_user.h +24 -0
  361. data/src/nginx/src/os/unix/ngx_writev_chain.c +181 -0
  362. data/src/nginx/src/os/unix/rfork_thread.S +73 -0
  363. metadata +419 -0
@@ -0,0 +1,84 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #ifndef _NGX_RBTREE_H_INCLUDED_
9
+ #define _NGX_RBTREE_H_INCLUDED_
10
+
11
+
12
+ #include <ngx_config.h>
13
+ #include <ngx_core.h>
14
+
15
+
16
+ typedef ngx_uint_t ngx_rbtree_key_t;
17
+ typedef ngx_int_t ngx_rbtree_key_int_t;
18
+
19
+
20
+ typedef struct ngx_rbtree_node_s ngx_rbtree_node_t;
21
+
22
+ struct ngx_rbtree_node_s {
23
+ ngx_rbtree_key_t key;
24
+ ngx_rbtree_node_t *left;
25
+ ngx_rbtree_node_t *right;
26
+ ngx_rbtree_node_t *parent;
27
+ u_char color;
28
+ u_char data;
29
+ };
30
+
31
+
32
+ typedef struct ngx_rbtree_s ngx_rbtree_t;
33
+
34
+ typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
35
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
36
+
37
+ struct ngx_rbtree_s {
38
+ ngx_rbtree_node_t *root;
39
+ ngx_rbtree_node_t *sentinel;
40
+ ngx_rbtree_insert_pt insert;
41
+ };
42
+
43
+
44
+ #define ngx_rbtree_init(tree, s, i) \
45
+ ngx_rbtree_sentinel_init(s); \
46
+ (tree)->root = s; \
47
+ (tree)->sentinel = s; \
48
+ (tree)->insert = i
49
+
50
+
51
+ void ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
52
+ ngx_rbtree_node_t *node);
53
+ void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
54
+ ngx_rbtree_node_t *node);
55
+ void ngx_rbtree_insert_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node,
56
+ ngx_rbtree_node_t *sentinel);
57
+ void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root,
58
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
59
+
60
+
61
+ #define ngx_rbt_red(node) ((node)->color = 1)
62
+ #define ngx_rbt_black(node) ((node)->color = 0)
63
+ #define ngx_rbt_is_red(node) ((node)->color)
64
+ #define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node))
65
+ #define ngx_rbt_copy_color(n1, n2) (n1->color = n2->color)
66
+
67
+
68
+ /* a sentinel must be black */
69
+
70
+ #define ngx_rbtree_sentinel_init(node) ngx_rbt_black(node)
71
+
72
+
73
+ static ngx_inline ngx_rbtree_node_t *
74
+ ngx_rbtree_min(ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
75
+ {
76
+ while (node->left != sentinel) {
77
+ node = node->left;
78
+ }
79
+
80
+ return node;
81
+ }
82
+
83
+
84
+ #endif /* _NGX_RBTREE_H_INCLUDED_ */
@@ -0,0 +1,206 @@
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
+
11
+
12
+ static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
13
+ static void ngx_libc_cdecl ngx_regex_free(void *p);
14
+
15
+
16
+ static ngx_pool_t *ngx_pcre_pool;
17
+
18
+
19
+ void
20
+ ngx_regex_init(void)
21
+ {
22
+ pcre_malloc = ngx_regex_malloc;
23
+ pcre_free = ngx_regex_free;
24
+ }
25
+
26
+
27
+ static ngx_inline void
28
+ ngx_regex_malloc_init(ngx_pool_t *pool)
29
+ {
30
+ #if (NGX_THREADS)
31
+ ngx_core_tls_t *tls;
32
+
33
+ if (ngx_threaded) {
34
+ tls = ngx_thread_get_tls(ngx_core_tls_key);
35
+ tls->pool = pool;
36
+ return;
37
+ }
38
+
39
+ #endif
40
+
41
+ ngx_pcre_pool = pool;
42
+ }
43
+
44
+
45
+ static ngx_inline void
46
+ ngx_regex_malloc_done(void)
47
+ {
48
+ #if (NGX_THREADS)
49
+ ngx_core_tls_t *tls;
50
+
51
+ if (ngx_threaded) {
52
+ tls = ngx_thread_get_tls(ngx_core_tls_key);
53
+ tls->pool = NULL;
54
+ return;
55
+ }
56
+
57
+ #endif
58
+
59
+ ngx_pcre_pool = NULL;
60
+ }
61
+
62
+
63
+ ngx_int_t
64
+ ngx_regex_compile(ngx_regex_compile_t *rc)
65
+ {
66
+ int n, erroff;
67
+ char *p;
68
+ const char *errstr;
69
+ ngx_regex_t *re;
70
+
71
+ ngx_regex_malloc_init(rc->pool);
72
+
73
+ re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
74
+ &errstr, &erroff, NULL);
75
+
76
+ /* ensure that there is no current pool */
77
+ ngx_regex_malloc_done();
78
+
79
+ if (re == NULL) {
80
+ if ((size_t) erroff == rc->pattern.len) {
81
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
82
+ "pcre_compile() failed: %s in \"%V\"",
83
+ errstr, &rc->pattern)
84
+ - rc->err.data;
85
+
86
+ } else {
87
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
88
+ "pcre_compile() failed: %s in \"%V\" at \"%s\"",
89
+ errstr, &rc->pattern, rc->pattern.data + erroff)
90
+ - rc->err.data;
91
+ }
92
+
93
+ return NGX_ERROR;
94
+ }
95
+
96
+ rc->regex = re;
97
+
98
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
99
+ if (n < 0) {
100
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
101
+ goto failed;
102
+ }
103
+
104
+ if (rc->captures == 0) {
105
+ return NGX_OK;
106
+ }
107
+
108
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
109
+ if (n < 0) {
110
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
111
+ goto failed;
112
+ }
113
+
114
+ if (rc->named_captures == 0) {
115
+ return NGX_OK;
116
+ }
117
+
118
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
119
+ if (n < 0) {
120
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
121
+ goto failed;
122
+ }
123
+
124
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
125
+ if (n < 0) {
126
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
127
+ goto failed;
128
+ }
129
+
130
+ return NGX_OK;
131
+
132
+ failed:
133
+
134
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
135
+ - rc->err.data;
136
+ return NGX_OK;
137
+ }
138
+
139
+
140
+ ngx_int_t
141
+ ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
142
+ {
143
+ ngx_int_t n;
144
+ ngx_uint_t i;
145
+ ngx_regex_elt_t *re;
146
+
147
+ re = a->elts;
148
+
149
+ for (i = 0; i < a->nelts; i++) {
150
+
151
+ n = ngx_regex_exec(re[i].regex, s, NULL, 0);
152
+
153
+ if (n == NGX_REGEX_NO_MATCHED) {
154
+ continue;
155
+ }
156
+
157
+ if (n < 0) {
158
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
159
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
160
+ n, s, re[i].name);
161
+ return NGX_ERROR;
162
+ }
163
+
164
+ /* match */
165
+
166
+ return NGX_OK;
167
+ }
168
+
169
+ return NGX_DECLINED;
170
+ }
171
+
172
+
173
+ static void * ngx_libc_cdecl
174
+ ngx_regex_malloc(size_t size)
175
+ {
176
+ ngx_pool_t *pool;
177
+ #if (NGX_THREADS)
178
+ ngx_core_tls_t *tls;
179
+
180
+ if (ngx_threaded) {
181
+ tls = ngx_thread_get_tls(ngx_core_tls_key);
182
+ pool = tls->pool;
183
+
184
+ } else {
185
+ pool = ngx_pcre_pool;
186
+ }
187
+
188
+ #else
189
+
190
+ pool = ngx_pcre_pool;
191
+
192
+ #endif
193
+
194
+ if (pool) {
195
+ return ngx_palloc(pool, size);
196
+ }
197
+
198
+ return NULL;
199
+ }
200
+
201
+
202
+ static void ngx_libc_cdecl
203
+ ngx_regex_free(void *p)
204
+ {
205
+ return;
206
+ }
@@ -0,0 +1,56 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #ifndef _NGX_REGEX_H_INCLUDED_
9
+ #define _NGX_REGEX_H_INCLUDED_
10
+
11
+
12
+ #include <ngx_config.h>
13
+ #include <ngx_core.h>
14
+
15
+ #include <pcre.h>
16
+
17
+
18
+ #define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */
19
+
20
+ #define NGX_REGEX_CASELESS PCRE_CASELESS
21
+
22
+ typedef pcre ngx_regex_t;
23
+
24
+
25
+ typedef struct {
26
+ ngx_str_t pattern;
27
+ ngx_pool_t *pool;
28
+ ngx_int_t options;
29
+
30
+ ngx_regex_t *regex;
31
+ int captures;
32
+ int named_captures;
33
+ int name_size;
34
+ u_char *names;
35
+ ngx_str_t err;
36
+ } ngx_regex_compile_t;
37
+
38
+
39
+ typedef struct {
40
+ ngx_regex_t *regex;
41
+ u_char *name;
42
+ } ngx_regex_elt_t;
43
+
44
+
45
+ void ngx_regex_init(void);
46
+ ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
47
+
48
+ #define ngx_regex_exec(re, s, captures, size) \
49
+ pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \
50
+ captures, size)
51
+ #define ngx_regex_exec_n "pcre_exec()"
52
+
53
+ ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
54
+
55
+
56
+ #endif /* _NGX_REGEX_H_INCLUDED_ */
@@ -0,0 +1,2201 @@
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_event.h>
11
+
12
+
13
+ #define NGX_RESOLVER_UDP_SIZE 4096
14
+
15
+
16
+ typedef struct {
17
+ u_char ident_hi;
18
+ u_char ident_lo;
19
+ u_char flags_hi;
20
+ u_char flags_lo;
21
+ u_char nqs_hi;
22
+ u_char nqs_lo;
23
+ u_char nan_hi;
24
+ u_char nan_lo;
25
+ u_char nns_hi;
26
+ u_char nns_lo;
27
+ u_char nar_hi;
28
+ u_char nar_lo;
29
+ } ngx_resolver_query_t;
30
+
31
+
32
+ typedef struct {
33
+ u_char type_hi;
34
+ u_char type_lo;
35
+ u_char class_hi;
36
+ u_char class_lo;
37
+ } ngx_resolver_qs_t;
38
+
39
+
40
+ typedef struct {
41
+ u_char type_hi;
42
+ u_char type_lo;
43
+ u_char class_hi;
44
+ u_char class_lo;
45
+ u_char ttl[4];
46
+ u_char len_hi;
47
+ u_char len_lo;
48
+ } ngx_resolver_an_t;
49
+
50
+
51
+ ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
52
+
53
+
54
+ static void ngx_resolver_cleanup(void *data);
55
+ static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
56
+ static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
57
+ ngx_resolver_ctx_t *ctx);
58
+ static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
59
+ ngx_queue_t *queue);
60
+ static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
61
+ ngx_resolver_node_t *rn);
62
+ static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn,
63
+ ngx_resolver_ctx_t *ctx);
64
+ static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
65
+ ngx_resolver_ctx_t *ctx);
66
+ static void ngx_resolver_resend_handler(ngx_event_t *ev);
67
+ static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
68
+ ngx_queue_t *queue);
69
+ static void ngx_resolver_read_response(ngx_event_t *rev);
70
+ static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf,
71
+ size_t n);
72
+ static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
73
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans);
74
+ static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
75
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan);
76
+ static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
77
+ ngx_str_t *name, uint32_t hash);
78
+ static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r,
79
+ in_addr_t addr);
80
+ static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
81
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
82
+ static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name,
83
+ u_char *buf, u_char *src, u_char *last);
84
+ static void ngx_resolver_timeout_handler(ngx_event_t *ev);
85
+ static void ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn);
86
+ static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size);
87
+ static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
88
+ static void ngx_resolver_free(ngx_resolver_t *r, void *p);
89
+ static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
90
+ static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
91
+ static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
92
+
93
+
94
+ ngx_resolver_t *
95
+ ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr)
96
+ {
97
+ ngx_resolver_t *r;
98
+ ngx_pool_cleanup_t *cln;
99
+ ngx_udp_connection_t *uc;
100
+
101
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
102
+ if (cln == NULL) {
103
+ return NULL;
104
+ }
105
+
106
+ cln->handler = ngx_resolver_cleanup;
107
+
108
+ r = ngx_calloc(sizeof(ngx_resolver_t), cf->log);
109
+ if (r == NULL) {
110
+ return NULL;
111
+ }
112
+
113
+ cln->data = r;
114
+
115
+ r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
116
+ if (r->event == NULL) {
117
+ return NULL;
118
+ }
119
+
120
+ ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
121
+ ngx_resolver_rbtree_insert_value);
122
+
123
+ ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel,
124
+ ngx_rbtree_insert_value);
125
+
126
+ ngx_queue_init(&r->name_resend_queue);
127
+ ngx_queue_init(&r->addr_resend_queue);
128
+
129
+ ngx_queue_init(&r->name_expire_queue);
130
+ ngx_queue_init(&r->addr_expire_queue);
131
+
132
+ r->event->handler = ngx_resolver_resend_handler;
133
+ r->event->data = r;
134
+ r->event->log = &cf->cycle->new_log;
135
+ r->ident = -1;
136
+
137
+ r->resend_timeout = 5;
138
+ r->expire = 30;
139
+ r->valid = 300;
140
+
141
+ r->log = &cf->cycle->new_log;
142
+ r->log_level = NGX_LOG_ERR;
143
+
144
+ if (addr) {
145
+ uc = ngx_calloc(sizeof(ngx_udp_connection_t), cf->log);
146
+ if (uc == NULL) {
147
+ return NULL;
148
+ }
149
+
150
+ r->udp_connection = uc;
151
+
152
+ uc->sockaddr = addr->sockaddr;
153
+ uc->socklen = addr->socklen;
154
+ uc->server = addr->name;
155
+ }
156
+
157
+ return r;
158
+ }
159
+
160
+
161
+ static void
162
+ ngx_resolver_cleanup(void *data)
163
+ {
164
+ ngx_resolver_t *r = data;
165
+
166
+ if (r) {
167
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
168
+ "cleanup resolver");
169
+
170
+ ngx_resolver_cleanup_tree(r, &r->name_rbtree);
171
+
172
+ ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
173
+
174
+ if (r->event) {
175
+ ngx_free(r->event);
176
+ }
177
+
178
+ if (r->udp_connection) {
179
+ if (r->udp_connection->connection) {
180
+ ngx_close_connection(r->udp_connection->connection);
181
+ }
182
+
183
+ ngx_free(r->udp_connection);
184
+ }
185
+
186
+ ngx_free(r);
187
+ }
188
+ }
189
+
190
+
191
+ static void
192
+ ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree)
193
+ {
194
+ ngx_resolver_ctx_t *ctx, *next;
195
+ ngx_resolver_node_t *rn;
196
+
197
+ while (tree->root != tree->sentinel) {
198
+
199
+ rn = (ngx_resolver_node_t *) ngx_rbtree_min(tree->root, tree->sentinel);
200
+
201
+ ngx_queue_remove(&rn->queue);
202
+
203
+ for (ctx = rn->waiting; ctx; ctx = next) {
204
+ next = ctx->next;
205
+
206
+ if (ctx->event) {
207
+ ngx_resolver_free(r, ctx->event);
208
+ }
209
+
210
+ ngx_resolver_free(r, ctx);
211
+ }
212
+
213
+ ngx_rbtree_delete(tree, &rn->node);
214
+
215
+ ngx_resolver_free_node(r, rn);
216
+ }
217
+ }
218
+
219
+
220
+ ngx_resolver_ctx_t *
221
+ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
222
+ {
223
+ in_addr_t addr;
224
+ ngx_resolver_ctx_t *ctx;
225
+
226
+ if (temp) {
227
+ addr = ngx_inet_addr(temp->name.data, temp->name.len);
228
+
229
+ if (addr != INADDR_NONE) {
230
+ temp->resolver = r;
231
+ temp->state = NGX_OK;
232
+ temp->naddrs = 1;
233
+ temp->addrs = &temp->addr;
234
+ temp->addr = addr;
235
+ temp->quick = 1;
236
+
237
+ return temp;
238
+ }
239
+ }
240
+
241
+ if (r->udp_connection == NULL) {
242
+ return NGX_NO_RESOLVER;
243
+ }
244
+
245
+ ctx = ngx_resolver_calloc(r, sizeof(ngx_resolver_ctx_t));
246
+
247
+ if (ctx) {
248
+ ctx->resolver = r;
249
+ }
250
+
251
+ return ctx;
252
+ }
253
+
254
+
255
+ ngx_int_t
256
+ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
257
+ {
258
+ ngx_int_t rc;
259
+ ngx_resolver_t *r;
260
+
261
+ r = ctx->resolver;
262
+
263
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
264
+ "resolve: \"%V\"", &ctx->name);
265
+
266
+ if (ctx->quick) {
267
+ ctx->handler(ctx);
268
+ return NGX_OK;
269
+ }
270
+
271
+ /* lock name mutex */
272
+
273
+ rc = ngx_resolve_name_locked(r, ctx);
274
+
275
+ if (rc == NGX_OK) {
276
+ return NGX_OK;
277
+ }
278
+
279
+ /* unlock name mutex */
280
+
281
+ if (rc == NGX_AGAIN) {
282
+ return NGX_OK;
283
+ }
284
+
285
+ /* NGX_ERROR */
286
+
287
+ if (ctx->event) {
288
+ ngx_resolver_free(r, ctx->event);
289
+ }
290
+
291
+ ngx_resolver_free(r, ctx);
292
+
293
+ return NGX_ERROR;
294
+ }
295
+
296
+
297
+ void
298
+ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
299
+ {
300
+ uint32_t hash;
301
+ ngx_resolver_t *r;
302
+ ngx_resolver_ctx_t *w, **p;
303
+ ngx_resolver_node_t *rn;
304
+
305
+ r = ctx->resolver;
306
+
307
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
308
+ "resolve name done: %i", ctx->state);
309
+
310
+ if (ctx->quick) {
311
+ return;
312
+ }
313
+
314
+ if (ctx->event && ctx->event->timer_set) {
315
+ ngx_del_timer(ctx->event);
316
+ }
317
+
318
+ /* lock name mutex */
319
+
320
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
321
+
322
+ hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
323
+
324
+ rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
325
+
326
+ if (rn) {
327
+ p = &rn->waiting;
328
+ w = rn->waiting;
329
+
330
+ while (w) {
331
+ if (w == ctx) {
332
+ *p = w->next;
333
+
334
+ goto done;
335
+ }
336
+
337
+ p = &w->next;
338
+ w = w->next;
339
+ }
340
+ }
341
+
342
+ ngx_log_error(NGX_LOG_ALERT, r->log, 0,
343
+ "could not cancel %V resolving", &ctx->name);
344
+ }
345
+
346
+ done:
347
+
348
+ ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
349
+
350
+ /* unlock name mutex */
351
+
352
+ /* lock alloc mutex */
353
+
354
+ if (ctx->event) {
355
+ ngx_resolver_free_locked(r, ctx->event);
356
+ }
357
+
358
+ ngx_resolver_free_locked(r, ctx);
359
+
360
+ /* unlock alloc mutex */
361
+ }
362
+
363
+
364
+ /* NGX_RESOLVE_A only */
365
+
366
+ static ngx_int_t
367
+ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
368
+ {
369
+ uint32_t hash;
370
+ in_addr_t addr, *addrs;
371
+ ngx_int_t rc;
372
+ ngx_uint_t naddrs;
373
+ ngx_resolver_ctx_t *next;
374
+ ngx_resolver_node_t *rn;
375
+
376
+ hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
377
+
378
+ rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
379
+
380
+ if (rn) {
381
+
382
+ if (rn->valid >= ngx_time()) {
383
+
384
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
385
+
386
+ ngx_queue_remove(&rn->queue);
387
+
388
+ rn->expire = ngx_time() + r->expire;
389
+
390
+ ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
391
+
392
+ naddrs = rn->naddrs;
393
+
394
+ if (naddrs) {
395
+
396
+ /* NGX_RESOLVE_A answer */
397
+
398
+ if (naddrs != 1) {
399
+ addr = 0;
400
+ addrs = ngx_resolver_dup(r, rn->u.addrs,
401
+ naddrs * sizeof(in_addr_t));
402
+ if (addrs == NULL) {
403
+ return NGX_ERROR;
404
+ }
405
+
406
+ } else {
407
+ addr = rn->u.addr;
408
+ addrs = NULL;
409
+ }
410
+
411
+ ctx->next = rn->waiting;
412
+ rn->waiting = NULL;
413
+
414
+ /* unlock name mutex */
415
+
416
+ do {
417
+ ctx->state = NGX_OK;
418
+ ctx->naddrs = naddrs;
419
+ ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
420
+ ctx->addr = addr;
421
+ next = ctx->next;
422
+
423
+ ctx->handler(ctx);
424
+
425
+ ctx = next;
426
+ } while (ctx);
427
+
428
+ if (addrs) {
429
+ ngx_resolver_free(r, addrs);
430
+ }
431
+
432
+ return NGX_OK;
433
+ }
434
+
435
+ /* NGX_RESOLVE_CNAME */
436
+
437
+ if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
438
+
439
+ ctx->name.len = rn->cnlen;
440
+ ctx->name.data = rn->u.cname;
441
+
442
+ return ngx_resolve_name_locked(r, ctx);
443
+ }
444
+
445
+ ctx->next = rn->waiting;
446
+ rn->waiting = NULL;
447
+
448
+ /* unlock name mutex */
449
+
450
+ do {
451
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
452
+ next = ctx->next;
453
+
454
+ ctx->handler(ctx);
455
+
456
+ ctx = next;
457
+ } while (ctx);
458
+
459
+ return NGX_OK;
460
+ }
461
+
462
+ if (rn->waiting) {
463
+
464
+ ctx->next = rn->waiting;
465
+ rn->waiting = ctx;
466
+ ctx->state = NGX_AGAIN;
467
+
468
+ return NGX_AGAIN;
469
+ }
470
+
471
+ ngx_queue_remove(&rn->queue);
472
+
473
+ /* lock alloc mutex */
474
+
475
+ ngx_resolver_free_locked(r, rn->query);
476
+ rn->query = NULL;
477
+
478
+ if (rn->cnlen) {
479
+ ngx_resolver_free_locked(r, rn->u.cname);
480
+ }
481
+
482
+ if (rn->naddrs > 1) {
483
+ ngx_resolver_free_locked(r, rn->u.addrs);
484
+ }
485
+
486
+ /* unlock alloc mutex */
487
+
488
+ } else {
489
+
490
+ rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
491
+ if (rn == NULL) {
492
+ return NGX_ERROR;
493
+ }
494
+
495
+ rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len);
496
+ if (rn->name == NULL) {
497
+ ngx_resolver_free(r, rn);
498
+ return NGX_ERROR;
499
+ }
500
+
501
+ rn->node.key = hash;
502
+ rn->nlen = (u_short) ctx->name.len;
503
+ rn->query = NULL;
504
+
505
+ ngx_rbtree_insert(&r->name_rbtree, &rn->node);
506
+ }
507
+
508
+ rc = ngx_resolver_create_name_query(rn, ctx);
509
+
510
+ if (rc == NGX_ERROR) {
511
+ goto failed;
512
+ }
513
+
514
+ if (rc == NGX_DECLINED) {
515
+ ngx_rbtree_delete(&r->name_rbtree, &rn->node);
516
+
517
+ ngx_resolver_free(r, rn->query);
518
+ ngx_resolver_free(r, rn->name);
519
+ ngx_resolver_free(r, rn);
520
+
521
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
522
+ ctx->handler(ctx);
523
+
524
+ return NGX_OK;
525
+ }
526
+
527
+ if (ngx_resolver_send_query(r, rn) != NGX_OK) {
528
+ goto failed;
529
+ }
530
+
531
+ if (ctx->event == NULL) {
532
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
533
+ if (ctx->event == NULL) {
534
+ goto failed;
535
+ }
536
+
537
+ ctx->event->handler = ngx_resolver_timeout_handler;
538
+ ctx->event->data = ctx;
539
+ ctx->event->log = r->log;
540
+ ctx->ident = -1;
541
+
542
+ ngx_add_timer(ctx->event, ctx->timeout);
543
+ }
544
+
545
+ if (ngx_queue_empty(&r->name_resend_queue)) {
546
+ ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
547
+ }
548
+
549
+ rn->expire = ngx_time() + r->resend_timeout;
550
+
551
+ ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
552
+
553
+ rn->cnlen = 0;
554
+ rn->naddrs = 0;
555
+ rn->valid = 0;
556
+ rn->waiting = ctx;
557
+
558
+ ctx->state = NGX_AGAIN;
559
+
560
+ return NGX_AGAIN;
561
+
562
+ failed:
563
+
564
+ ngx_rbtree_delete(&r->name_rbtree, &rn->node);
565
+
566
+ if (rn->query) {
567
+ ngx_resolver_free(r, rn->query);
568
+ }
569
+
570
+ ngx_resolver_free(r, rn->name);
571
+
572
+ ngx_resolver_free(r, rn);
573
+
574
+ return NGX_ERROR;
575
+ }
576
+
577
+
578
+ ngx_int_t
579
+ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
580
+ {
581
+ u_char *name;
582
+ ngx_resolver_t *r;
583
+ ngx_resolver_node_t *rn;
584
+
585
+ r = ctx->resolver;
586
+
587
+ ctx->addr = ntohl(ctx->addr);
588
+
589
+ /* lock addr mutex */
590
+
591
+ rn = ngx_resolver_lookup_addr(r, ctx->addr);
592
+
593
+ if (rn) {
594
+
595
+ if (rn->valid >= ngx_time()) {
596
+
597
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
598
+
599
+ ngx_queue_remove(&rn->queue);
600
+
601
+ rn->expire = ngx_time() + r->expire;
602
+
603
+ ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
604
+
605
+ name = ngx_resolver_dup(r, rn->name, rn->nlen);
606
+ if (name == NULL) {
607
+ goto failed;
608
+ }
609
+
610
+ ctx->name.len = rn->nlen;
611
+ ctx->name.data = name;
612
+
613
+ /* unlock addr mutex */
614
+
615
+ ctx->state = NGX_OK;
616
+
617
+ ctx->handler(ctx);
618
+
619
+ ngx_resolver_free(r, name);
620
+
621
+ return NGX_OK;
622
+ }
623
+
624
+ if (rn->waiting) {
625
+
626
+ ctx->next = rn->waiting;
627
+ rn->waiting = ctx;
628
+ ctx->state = NGX_AGAIN;
629
+
630
+ /* unlock addr mutex */
631
+
632
+ return NGX_OK;
633
+ }
634
+
635
+ ngx_queue_remove(&rn->queue);
636
+
637
+ ngx_resolver_free(r, rn->query);
638
+ rn->query = NULL;
639
+
640
+ } else {
641
+ rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
642
+ if (rn == NULL) {
643
+ goto failed;
644
+ }
645
+
646
+ rn->node.key = ctx->addr;
647
+ rn->query = NULL;
648
+
649
+ ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
650
+ }
651
+
652
+ if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
653
+ goto failed;
654
+ }
655
+
656
+ if (ngx_resolver_send_query(r, rn) != NGX_OK) {
657
+ goto failed;
658
+ }
659
+
660
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
661
+ if (ctx->event == NULL) {
662
+ goto failed;
663
+ }
664
+
665
+ ctx->event->handler = ngx_resolver_timeout_handler;
666
+ ctx->event->data = ctx;
667
+ ctx->event->log = r->log;
668
+ ctx->ident = -1;
669
+
670
+ ngx_add_timer(ctx->event, ctx->timeout);
671
+
672
+ if (ngx_queue_empty(&r->addr_resend_queue)) {
673
+ ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
674
+ }
675
+
676
+ rn->expire = ngx_time() + r->resend_timeout;
677
+
678
+ ngx_queue_insert_head(&r->addr_resend_queue, &rn->queue);
679
+
680
+ rn->cnlen = 0;
681
+ rn->naddrs = 0;
682
+ rn->name = NULL;
683
+ rn->nlen = 0;
684
+ rn->valid = 0;
685
+ rn->waiting = ctx;
686
+
687
+ /* unlock addr mutex */
688
+
689
+ ctx->state = NGX_AGAIN;
690
+
691
+ return NGX_OK;
692
+
693
+ failed:
694
+
695
+ if (rn) {
696
+ ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
697
+
698
+ if (rn->query) {
699
+ ngx_resolver_free(r, rn->query);
700
+ }
701
+
702
+ ngx_resolver_free(r, rn);
703
+ }
704
+
705
+ /* unlock addr mutex */
706
+
707
+ if (ctx->event) {
708
+ ngx_resolver_free(r, ctx->event);
709
+ }
710
+
711
+ ngx_resolver_free(r, ctx);
712
+
713
+ return NGX_ERROR;
714
+ }
715
+
716
+
717
+ void
718
+ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
719
+ {
720
+ in_addr_t addr;
721
+ ngx_resolver_t *r;
722
+ ngx_resolver_ctx_t *w, **p;
723
+ ngx_resolver_node_t *rn;
724
+
725
+ r = ctx->resolver;
726
+
727
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
728
+ "resolve addr done: %i", ctx->state);
729
+
730
+ if (ctx->event && ctx->event->timer_set) {
731
+ ngx_del_timer(ctx->event);
732
+ }
733
+
734
+ /* lock addr mutex */
735
+
736
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
737
+
738
+ rn = ngx_resolver_lookup_addr(r, ctx->addr);
739
+
740
+ if (rn) {
741
+ p = &rn->waiting;
742
+ w = rn->waiting;
743
+
744
+ while (w) {
745
+ if (w == ctx) {
746
+ *p = w->next;
747
+
748
+ goto done;
749
+ }
750
+
751
+ p = &w->next;
752
+ w = w->next;
753
+ }
754
+ }
755
+
756
+ addr = ntohl(ctx->addr);
757
+
758
+ ngx_log_error(NGX_LOG_ALERT, r->log, 0,
759
+ "could not cancel %ud.%ud.%ud.%ud resolving",
760
+ (addr >> 24) & 0xff, (addr >> 16) & 0xff,
761
+ (addr >> 8) & 0xff, addr & 0xff);
762
+ }
763
+
764
+ done:
765
+
766
+ ngx_resolver_expire(r, &r->addr_rbtree, &r->addr_expire_queue);
767
+
768
+ /* unlock addr mutex */
769
+
770
+ /* lock alloc mutex */
771
+
772
+ if (ctx->event) {
773
+ ngx_resolver_free_locked(r, ctx->event);
774
+ }
775
+
776
+ ngx_resolver_free_locked(r, ctx);
777
+
778
+ /* unlock alloc mutex */
779
+ }
780
+
781
+
782
+ static void
783
+ ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
784
+ {
785
+ time_t now;
786
+ ngx_uint_t i;
787
+ ngx_queue_t *q;
788
+ ngx_resolver_node_t *rn;
789
+
790
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver expire");
791
+
792
+ now = ngx_time();
793
+
794
+ for (i = 0; i < 2; i++) {
795
+ if (ngx_queue_empty(queue)) {
796
+ return;
797
+ }
798
+
799
+ q = ngx_queue_last(queue);
800
+
801
+ rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
802
+
803
+ if (now <= rn->expire) {
804
+ return;
805
+ }
806
+
807
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
808
+ "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name);
809
+
810
+ ngx_queue_remove(q);
811
+
812
+ ngx_rbtree_delete(tree, &rn->node);
813
+
814
+ ngx_resolver_free_node(r, rn);
815
+ }
816
+ }
817
+
818
+
819
+ static ngx_int_t
820
+ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
821
+ {
822
+ ssize_t n;
823
+ ngx_udp_connection_t *uc;
824
+
825
+ uc = r->udp_connection;
826
+
827
+ if (uc->connection == NULL) {
828
+
829
+ uc->log = *r->log;
830
+ uc->log.handler = ngx_resolver_log_error;
831
+ uc->log.data = uc;
832
+ uc->log.action = "resolving";
833
+
834
+ if (ngx_udp_connect(uc) != NGX_OK) {
835
+ return NGX_ERROR;
836
+ }
837
+
838
+ uc->connection->data = r;
839
+ uc->connection->read->handler = ngx_resolver_read_response;
840
+ uc->connection->read->resolver = 1;
841
+ }
842
+
843
+ n = ngx_send(uc->connection, rn->query, rn->qlen);
844
+
845
+ if (n == -1) {
846
+ return NGX_ERROR;
847
+ }
848
+
849
+ if ((size_t) n != (size_t) rn->qlen) {
850
+ ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
851
+ return NGX_ERROR;
852
+ }
853
+
854
+ return NGX_OK;
855
+ }
856
+
857
+
858
+ static void
859
+ ngx_resolver_resend_handler(ngx_event_t *ev)
860
+ {
861
+ time_t timer, atimer, ntimer;
862
+ ngx_resolver_t *r;
863
+
864
+ r = ev->data;
865
+
866
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0,
867
+ "resolver resend handler");
868
+
869
+ /* lock name mutex */
870
+
871
+ ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue);
872
+
873
+ /* unlock name mutex */
874
+
875
+ /* lock addr mutex */
876
+
877
+ atimer = ngx_resolver_resend(r, &r->addr_rbtree, &r->addr_resend_queue);
878
+
879
+ /* unlock addr mutex */
880
+
881
+ if (ntimer == 0) {
882
+ timer = atimer;
883
+
884
+ } else if (atimer == 0) {
885
+ timer = ntimer;
886
+
887
+ } else {
888
+ timer = (atimer < ntimer) ? atimer : ntimer;
889
+ }
890
+
891
+ if (timer) {
892
+ ngx_add_timer(r->event, (ngx_msec_t) (timer * 1000));
893
+ }
894
+ }
895
+
896
+
897
+ static time_t
898
+ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
899
+ {
900
+ time_t now;
901
+ ngx_queue_t *q;
902
+ ngx_resolver_node_t *rn;
903
+
904
+ now = ngx_time();
905
+
906
+ for ( ;; ) {
907
+ if (ngx_queue_empty(queue)) {
908
+ return 0;
909
+ }
910
+
911
+ q = ngx_queue_last(queue);
912
+
913
+ rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
914
+
915
+ if (now < rn->expire) {
916
+ return rn->expire - now;
917
+ }
918
+
919
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
920
+ "resolver resend \"%*s\" %p",
921
+ (size_t) rn->nlen, rn->name, rn->waiting);
922
+
923
+ ngx_queue_remove(q);
924
+
925
+ if (rn->waiting) {
926
+
927
+ if (ngx_resolver_send_query(r, rn) == NGX_OK) {
928
+
929
+ rn->expire = now + r->resend_timeout;
930
+
931
+ ngx_queue_insert_head(queue, &rn->queue);
932
+ }
933
+
934
+ continue;
935
+ }
936
+
937
+ ngx_rbtree_delete(tree, &rn->node);
938
+
939
+ ngx_resolver_free_node(r, rn);
940
+ }
941
+ }
942
+
943
+
944
+ static void
945
+ ngx_resolver_read_response(ngx_event_t *rev)
946
+ {
947
+ ssize_t n;
948
+ ngx_connection_t *c;
949
+ u_char buf[NGX_RESOLVER_UDP_SIZE];
950
+
951
+ c = rev->data;
952
+
953
+ do {
954
+ n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
955
+
956
+ if (n < 0) {
957
+ return;
958
+ }
959
+
960
+ ngx_resolver_process_response(c->data, buf, n);
961
+
962
+ } while (rev->ready);
963
+ }
964
+
965
+
966
+ static void
967
+ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
968
+ {
969
+ char *err;
970
+ size_t len;
971
+ ngx_uint_t i, times, ident, qident, flags, code, nqs, nan,
972
+ qtype, qclass;
973
+ ngx_queue_t *q;
974
+ ngx_resolver_qs_t *qs;
975
+ ngx_resolver_node_t *rn;
976
+ ngx_resolver_query_t *query;
977
+
978
+ if ((size_t) n < sizeof(ngx_resolver_query_t)) {
979
+ goto short_response;
980
+ }
981
+
982
+ query = (ngx_resolver_query_t *) buf;
983
+
984
+ ident = (query->ident_hi << 8) + query->ident_lo;
985
+ flags = (query->flags_hi << 8) + query->flags_lo;
986
+ nqs = (query->nqs_hi << 8) + query->nqs_lo;
987
+ nan = (query->nan_hi << 8) + query->nan_lo;
988
+
989
+ ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
990
+ "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui",
991
+ ident, flags, nqs, nan,
992
+ (query->nns_hi << 8) + query->nns_lo,
993
+ (query->nar_hi << 8) + query->nar_lo);
994
+
995
+ if (!(flags & 0x8000)) {
996
+ ngx_log_error(r->log_level, r->log, 0,
997
+ "invalid DNS response %ui fl:%04Xui", ident, flags);
998
+ return;
999
+ }
1000
+
1001
+ code = flags & 0x7f;
1002
+
1003
+ if (code == NGX_RESOLVE_FORMERR) {
1004
+
1005
+ times = 0;
1006
+
1007
+ for (q = ngx_queue_head(&r->name_resend_queue);
1008
+ q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100;
1009
+ q = ngx_queue_next(q))
1010
+ {
1011
+ rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
1012
+ qident = (rn->query[0] << 8) + rn->query[1];
1013
+
1014
+ if (qident == ident) {
1015
+ ngx_log_error(r->log_level, r->log, 0,
1016
+ "DNS error (%ui: %s), query id:%ui, name:\"%*s\"",
1017
+ code, ngx_resolver_strerror(code), ident,
1018
+ rn->nlen, rn->name);
1019
+ return;
1020
+ }
1021
+ }
1022
+
1023
+ goto dns_error;
1024
+ }
1025
+
1026
+ if (code > NGX_RESOLVE_REFUSED) {
1027
+ goto dns_error;
1028
+ }
1029
+
1030
+ if (nqs != 1) {
1031
+ err = "invalid number of questions in DNS response";
1032
+ goto done;
1033
+ }
1034
+
1035
+ i = sizeof(ngx_resolver_query_t);
1036
+
1037
+ while (i < (ngx_uint_t) n) {
1038
+ if (buf[i] == '\0') {
1039
+ goto found;
1040
+ }
1041
+
1042
+ len = buf[i];
1043
+ i += 1 + len;
1044
+ }
1045
+
1046
+ goto short_response;
1047
+
1048
+ found:
1049
+
1050
+ if (i++ == 0) {
1051
+ err = "zero-length domain name in DNS response";
1052
+ goto done;
1053
+ }
1054
+
1055
+ if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t))
1056
+ > (ngx_uint_t) n)
1057
+ {
1058
+ goto short_response;
1059
+ }
1060
+
1061
+ qs = (ngx_resolver_qs_t *) &buf[i];
1062
+
1063
+ qtype = (qs->type_hi << 8) + qs->type_lo;
1064
+ qclass = (qs->class_hi << 8) + qs->class_lo;
1065
+
1066
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
1067
+ "resolver DNS response qt:%ui cl:%ui", qtype, qclass);
1068
+
1069
+ if (qclass != 1) {
1070
+ ngx_log_error(r->log_level, r->log, 0,
1071
+ "unknown query class %ui in DNS response", qclass);
1072
+ return;
1073
+ }
1074
+
1075
+ switch (qtype) {
1076
+
1077
+ case NGX_RESOLVE_A:
1078
+
1079
+ ngx_resolver_process_a(r, buf, n, ident, code, nan,
1080
+ i + sizeof(ngx_resolver_qs_t));
1081
+
1082
+ break;
1083
+
1084
+ case NGX_RESOLVE_PTR:
1085
+
1086
+ ngx_resolver_process_ptr(r, buf, n, ident, code, nan);
1087
+
1088
+ break;
1089
+
1090
+ default:
1091
+ ngx_log_error(r->log_level, r->log, 0,
1092
+ "unknown query type %ui in DNS response", qtype);
1093
+ return;
1094
+ }
1095
+
1096
+ return;
1097
+
1098
+ short_response:
1099
+
1100
+ err = "short dns response";
1101
+
1102
+ done:
1103
+
1104
+ ngx_log_error(r->log_level, r->log, 0, err);
1105
+
1106
+ return;
1107
+
1108
+ dns_error:
1109
+
1110
+ ngx_log_error(r->log_level, r->log, 0,
1111
+ "DNS error (%ui: %s), query id:%ui",
1112
+ code, ngx_resolver_strerror(code), ident);
1113
+ return;
1114
+ }
1115
+
1116
+
1117
+ static void
1118
+ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1119
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans)
1120
+ {
1121
+ char *err;
1122
+ u_char *cname;
1123
+ size_t len;
1124
+ uint32_t hash;
1125
+ in_addr_t addr, *addrs;
1126
+ ngx_str_t name;
1127
+ ngx_uint_t qtype, qident, naddrs, a, i, n, start;
1128
+ ngx_resolver_an_t *an;
1129
+ ngx_resolver_ctx_t *ctx, *next;
1130
+ ngx_resolver_node_t *rn;
1131
+
1132
+ if (ngx_resolver_copy(r, &name, buf, &buf[12], &buf[last]) != NGX_OK) {
1133
+ return;
1134
+ }
1135
+
1136
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
1137
+
1138
+ hash = ngx_crc32_short(name.data, name.len);
1139
+
1140
+ /* lock name mutex */
1141
+
1142
+ rn = ngx_resolver_lookup_name(r, &name, hash);
1143
+
1144
+ if (rn == NULL || rn->query == NULL) {
1145
+ ngx_log_error(r->log_level, r->log, 0,
1146
+ "unexpected response for %V", &name);
1147
+ goto failed;
1148
+ }
1149
+
1150
+ qident = (rn->query[0] << 8) + rn->query[1];
1151
+
1152
+ if (ident != qident) {
1153
+ ngx_log_error(r->log_level, r->log, 0,
1154
+ "wrong ident %ui response for %V, expect %ui",
1155
+ ident, &name, qident);
1156
+ goto failed;
1157
+ }
1158
+
1159
+ ngx_resolver_free(r, name.data);
1160
+
1161
+ if (code == 0 && nan == 0) {
1162
+ code = 3; /* NXDOMAIN */
1163
+ }
1164
+
1165
+ if (code) {
1166
+ next = rn->waiting;
1167
+ rn->waiting = NULL;
1168
+
1169
+ ngx_queue_remove(&rn->queue);
1170
+
1171
+ ngx_rbtree_delete(&r->name_rbtree, &rn->node);
1172
+
1173
+ ngx_resolver_free_node(r, rn);
1174
+
1175
+ /* unlock name mutex */
1176
+
1177
+ while (next) {
1178
+ ctx = next;
1179
+ ctx->state = code;
1180
+ next = ctx->next;
1181
+
1182
+ ctx->handler(ctx);
1183
+ }
1184
+
1185
+ return;
1186
+ }
1187
+
1188
+ i = ans;
1189
+ naddrs = 0;
1190
+ addr = 0;
1191
+ addrs = NULL;
1192
+ cname = NULL;
1193
+ qtype = 0;
1194
+
1195
+ for (a = 0; a < nan; a++) {
1196
+
1197
+ start = i;
1198
+
1199
+ while (i < last) {
1200
+
1201
+ if (buf[i] & 0xc0) {
1202
+ i += 2;
1203
+ goto found;
1204
+ }
1205
+
1206
+ if (buf[i] == 0) {
1207
+ i++;
1208
+ goto test_length;
1209
+ }
1210
+
1211
+ i += 1 + buf[i];
1212
+ }
1213
+
1214
+ goto short_response;
1215
+
1216
+ test_length:
1217
+
1218
+ if (i - start < 2) {
1219
+ err = "invalid name in dns response";
1220
+ goto invalid;
1221
+ }
1222
+
1223
+ found:
1224
+
1225
+ if (i + sizeof(ngx_resolver_an_t) >= last) {
1226
+ goto short_response;
1227
+ }
1228
+
1229
+ an = (ngx_resolver_an_t *) &buf[i];
1230
+
1231
+ qtype = (an->type_hi << 8) + an->type_lo;
1232
+ len = (an->len_hi << 8) + an->len_lo;
1233
+
1234
+ if (qtype == NGX_RESOLVE_A) {
1235
+
1236
+ i += sizeof(ngx_resolver_an_t);
1237
+
1238
+ if (i + len > last) {
1239
+ goto short_response;
1240
+ }
1241
+
1242
+ addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)
1243
+ + (buf[i + 2] << 8) + (buf[i + 3]));
1244
+
1245
+ naddrs++;
1246
+
1247
+ i += len;
1248
+
1249
+ } else if (qtype == NGX_RESOLVE_CNAME) {
1250
+ cname = &buf[i] + sizeof(ngx_resolver_an_t);
1251
+ i += sizeof(ngx_resolver_an_t) + len;
1252
+
1253
+ } else if (qtype == NGX_RESOLVE_DNAME) {
1254
+ i += sizeof(ngx_resolver_an_t) + len;
1255
+
1256
+ } else {
1257
+ ngx_log_error(r->log_level, r->log, 0,
1258
+ "unexpected qtype %ui", qtype);
1259
+ }
1260
+ }
1261
+
1262
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
1263
+ "resolver naddrs:%ui cname:%p", naddrs, cname);
1264
+
1265
+ if (naddrs) {
1266
+
1267
+ if (naddrs == 1) {
1268
+ rn->u.addr = addr;
1269
+
1270
+ } else {
1271
+
1272
+ addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
1273
+ if (addrs == NULL) {
1274
+ return;
1275
+ }
1276
+
1277
+ n = 0;
1278
+ i = ans;
1279
+
1280
+ for (a = 0; a < nan; a++) {
1281
+
1282
+ for ( ;; ) {
1283
+
1284
+ if (buf[i] & 0xc0) {
1285
+ i += 2;
1286
+ goto ok;
1287
+ }
1288
+
1289
+ if (buf[i] == 0) {
1290
+ i++;
1291
+ goto ok;
1292
+ }
1293
+
1294
+ i += 1 + buf[i];
1295
+ }
1296
+
1297
+ ok:
1298
+
1299
+ an = (ngx_resolver_an_t *) &buf[i];
1300
+
1301
+ qtype = (an->type_hi << 8) + an->type_lo;
1302
+ len = (an->len_hi << 8) + an->len_lo;
1303
+
1304
+ i += sizeof(ngx_resolver_an_t);
1305
+
1306
+ if (qtype == NGX_RESOLVE_A) {
1307
+
1308
+ addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
1309
+ + (buf[i + 2] << 8) + (buf[i + 3]));
1310
+
1311
+ if (n == naddrs) {
1312
+ break;
1313
+ }
1314
+ }
1315
+
1316
+ i += len;
1317
+ }
1318
+
1319
+ rn->u.addrs = addrs;
1320
+
1321
+ addrs = ngx_resolver_dup(r, rn->u.addrs,
1322
+ naddrs * sizeof(in_addr_t));
1323
+ if (addrs == NULL) {
1324
+ return;
1325
+ }
1326
+ }
1327
+
1328
+ rn->naddrs = (u_short) naddrs;
1329
+
1330
+ ngx_queue_remove(&rn->queue);
1331
+
1332
+ rn->valid = ngx_time() + r->valid;
1333
+ rn->expire = ngx_time() + r->expire;
1334
+
1335
+ ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
1336
+
1337
+ next = rn->waiting;
1338
+ rn->waiting = NULL;
1339
+
1340
+ /* unlock name mutex */
1341
+
1342
+ while (next) {
1343
+ ctx = next;
1344
+ ctx->state = NGX_OK;
1345
+ ctx->naddrs = naddrs;
1346
+ ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
1347
+ ctx->addr = addr;
1348
+ next = ctx->next;
1349
+
1350
+ ctx->handler(ctx);
1351
+ }
1352
+
1353
+ if (naddrs > 1) {
1354
+ ngx_resolver_free(r, addrs);
1355
+ }
1356
+
1357
+ return;
1358
+
1359
+ } else if (cname) {
1360
+
1361
+ /* CNAME only */
1362
+
1363
+ if (ngx_resolver_copy(r, &name, buf, cname, &buf[last]) != NGX_OK) {
1364
+ return;
1365
+ }
1366
+
1367
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
1368
+ "resolver cname:\"%V\"", &name);
1369
+
1370
+ ngx_queue_remove(&rn->queue);
1371
+
1372
+ rn->cnlen = (u_short) name.len;
1373
+ rn->u.cname = name.data;
1374
+ rn->valid = ngx_time() + r->valid;
1375
+ rn->expire = ngx_time() + r->expire;
1376
+
1377
+ ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
1378
+
1379
+ ctx = rn->waiting;
1380
+ rn->waiting = NULL;
1381
+
1382
+ if (ctx) {
1383
+ ctx->name = name;
1384
+
1385
+ (void) ngx_resolve_name_locked(r, ctx);
1386
+ }
1387
+
1388
+ return;
1389
+ }
1390
+
1391
+ ngx_log_error(r->log_level, r->log, 0,
1392
+ "no A or CNAME types in DNS responses, unknown query type: %ui",
1393
+ qtype);
1394
+ return;
1395
+
1396
+ short_response:
1397
+
1398
+ err = "short dns response";
1399
+
1400
+ invalid:
1401
+
1402
+ /* unlock name mutex */
1403
+
1404
+ ngx_log_error(r->log_level, r->log, 0, err);
1405
+
1406
+ return;
1407
+
1408
+ failed:
1409
+
1410
+ /* unlock name mutex */
1411
+
1412
+ ngx_resolver_free(r, name.data);
1413
+
1414
+ return;
1415
+ }
1416
+
1417
+
1418
+ static void
1419
+ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
1420
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan)
1421
+ {
1422
+ char *err;
1423
+ size_t len;
1424
+ in_addr_t addr;
1425
+ ngx_int_t digit;
1426
+ ngx_str_t name;
1427
+ ngx_uint_t i, mask, qident;
1428
+ ngx_resolver_an_t *an;
1429
+ ngx_resolver_ctx_t *ctx, *next;
1430
+ ngx_resolver_node_t *rn;
1431
+
1432
+ if (ngx_resolver_copy(r, NULL, buf, &buf[12], &buf[n]) != NGX_OK) {
1433
+ goto invalid_in_addr_arpa;
1434
+ }
1435
+
1436
+ addr = 0;
1437
+ i = 12;
1438
+
1439
+ for (mask = 0; mask < 32; mask += 8) {
1440
+ len = buf[i++];
1441
+
1442
+ digit = ngx_atoi(&buf[i], len);
1443
+ if (digit == NGX_ERROR || digit > 255) {
1444
+ goto invalid_in_addr_arpa;
1445
+ }
1446
+
1447
+ addr += digit << mask;
1448
+ i += len;
1449
+ }
1450
+
1451
+ if (ngx_strcmp(&buf[i], "\7in-addr\4arpa") != 0) {
1452
+ goto invalid_in_addr_arpa;
1453
+ }
1454
+
1455
+ /* lock addr mutex */
1456
+
1457
+ rn = ngx_resolver_lookup_addr(r, addr);
1458
+
1459
+ if (rn == NULL || rn->query == NULL) {
1460
+ ngx_log_error(r->log_level, r->log, 0,
1461
+ "unexpected response for %ud.%ud.%ud.%ud",
1462
+ (addr >> 24) & 0xff, (addr >> 16) & 0xff,
1463
+ (addr >> 8) & 0xff, addr & 0xff);
1464
+ goto failed;
1465
+ }
1466
+
1467
+ qident = (rn->query[0] << 8) + rn->query[1];
1468
+
1469
+ if (ident != qident) {
1470
+ ngx_log_error(r->log_level, r->log, 0,
1471
+ "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",
1472
+ ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
1473
+ (addr >> 8) & 0xff, addr & 0xff, qident);
1474
+ goto failed;
1475
+ }
1476
+
1477
+ if (code == 0 && nan == 0) {
1478
+ code = 3; /* NXDOMAIN */
1479
+ }
1480
+
1481
+ if (code) {
1482
+ next = rn->waiting;
1483
+ rn->waiting = NULL;
1484
+
1485
+ ngx_queue_remove(&rn->queue);
1486
+
1487
+ ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
1488
+
1489
+ ngx_resolver_free_node(r, rn);
1490
+
1491
+ /* unlock addr mutex */
1492
+
1493
+ while (next) {
1494
+ ctx = next;
1495
+ ctx->state = code;
1496
+ next = ctx->next;
1497
+
1498
+ ctx->handler(ctx);
1499
+ }
1500
+
1501
+ return;
1502
+ }
1503
+
1504
+ i += sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t);
1505
+
1506
+ if (i + 2 + sizeof(ngx_resolver_an_t) > (ngx_uint_t) n) {
1507
+ goto short_response;
1508
+ }
1509
+
1510
+ /* compression pointer to "XX.XX.XX.XX.in-addr.arpa */
1511
+
1512
+ if (buf[i] != 0xc0 || buf[i + 1] != 0x0c) {
1513
+ err = "invalid in-addr.arpa name in DNS response";
1514
+ goto invalid;
1515
+ }
1516
+
1517
+ an = (ngx_resolver_an_t *) &buf[i + 2];
1518
+
1519
+ len = (an->len_hi << 8) + an->len_lo;
1520
+
1521
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
1522
+ "resolver qt:%ui cl:%ui len:%uz",
1523
+ (an->type_hi << 8) + an->type_lo,
1524
+ (an->class_hi << 8) + an->class_lo, len);
1525
+
1526
+ i += 2 + sizeof(ngx_resolver_an_t);
1527
+
1528
+ if (i + len > (ngx_uint_t) n) {
1529
+ goto short_response;
1530
+ }
1531
+
1532
+ if (ngx_resolver_copy(r, &name, buf, &buf[i], &buf[n]) != NGX_OK) {
1533
+ return;
1534
+ }
1535
+
1536
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver an:%V", &name);
1537
+
1538
+ if (name.len != (size_t) rn->nlen
1539
+ || ngx_strncmp(name.data, rn->name, name.len) != 0)
1540
+ {
1541
+ if (rn->nlen) {
1542
+ ngx_resolver_free(r, rn->name);
1543
+ }
1544
+
1545
+ rn->nlen = (u_short) name.len;
1546
+ rn->name = name.data;
1547
+
1548
+ name.data = ngx_resolver_dup(r, rn->name, name.len);
1549
+ if (name.data == NULL) {
1550
+ goto failed;
1551
+ }
1552
+ }
1553
+
1554
+ ngx_queue_remove(&rn->queue);
1555
+
1556
+ rn->valid = ngx_time() + r->valid;
1557
+ rn->expire = ngx_time() + r->expire;
1558
+
1559
+ ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
1560
+
1561
+ next = rn->waiting;
1562
+ rn->waiting = NULL;
1563
+
1564
+ /* unlock addr mutex */
1565
+
1566
+ while (next) {
1567
+ ctx = next;
1568
+ ctx->state = NGX_OK;
1569
+ ctx->name = name;
1570
+ next = ctx->next;
1571
+
1572
+ ctx->handler(ctx);
1573
+ }
1574
+
1575
+ ngx_resolver_free(r, name.data);
1576
+
1577
+ return;
1578
+
1579
+ invalid_in_addr_arpa:
1580
+
1581
+ ngx_log_error(r->log_level, r->log, 0,
1582
+ "invalid in-addr.arpa name in DNS response");
1583
+ return;
1584
+
1585
+ short_response:
1586
+
1587
+ err = "short DNS response";
1588
+
1589
+ invalid:
1590
+
1591
+ /* unlock addr mutex */
1592
+
1593
+ ngx_log_error(r->log_level, r->log, 0, err);
1594
+
1595
+ return;
1596
+
1597
+ failed:
1598
+
1599
+ /* unlock addr mutex */
1600
+
1601
+ return;
1602
+ }
1603
+
1604
+
1605
+ static ngx_resolver_node_t *
1606
+ ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
1607
+ {
1608
+ ngx_int_t rc;
1609
+ ngx_rbtree_node_t *node, *sentinel;
1610
+ ngx_resolver_node_t *rn;
1611
+
1612
+ node = r->name_rbtree.root;
1613
+ sentinel = r->name_rbtree.sentinel;
1614
+
1615
+ while (node != sentinel) {
1616
+
1617
+ if (hash < node->key) {
1618
+ node = node->left;
1619
+ continue;
1620
+ }
1621
+
1622
+ if (hash > node->key) {
1623
+ node = node->right;
1624
+ continue;
1625
+ }
1626
+
1627
+ /* hash == node->key */
1628
+
1629
+ rn = (ngx_resolver_node_t *) node;
1630
+
1631
+ rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
1632
+
1633
+ if (rc == 0) {
1634
+ return rn;
1635
+ }
1636
+
1637
+ node = (rc < 0) ? node->left : node->right;
1638
+ }
1639
+
1640
+ /* not found */
1641
+
1642
+ return NULL;
1643
+ }
1644
+
1645
+
1646
+ static ngx_resolver_node_t *
1647
+ ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr)
1648
+ {
1649
+ ngx_rbtree_node_t *node, *sentinel;
1650
+
1651
+ node = r->addr_rbtree.root;
1652
+ sentinel = r->addr_rbtree.sentinel;
1653
+
1654
+ while (node != sentinel) {
1655
+
1656
+ if (addr < node->key) {
1657
+ node = node->left;
1658
+ continue;
1659
+ }
1660
+
1661
+ if (addr > node->key) {
1662
+ node = node->right;
1663
+ continue;
1664
+ }
1665
+
1666
+ /* addr == node->key */
1667
+
1668
+ return (ngx_resolver_node_t *) node;
1669
+ }
1670
+
1671
+ /* not found */
1672
+
1673
+ return NULL;
1674
+ }
1675
+
1676
+
1677
+ static void
1678
+ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
1679
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
1680
+ {
1681
+ ngx_rbtree_node_t **p;
1682
+ ngx_resolver_node_t *rn, *rn_temp;
1683
+
1684
+ for ( ;; ) {
1685
+
1686
+ if (node->key < temp->key) {
1687
+
1688
+ p = &temp->left;
1689
+
1690
+ } else if (node->key > temp->key) {
1691
+
1692
+ p = &temp->right;
1693
+
1694
+ } else { /* node->key == temp->key */
1695
+
1696
+ rn = (ngx_resolver_node_t *) node;
1697
+ rn_temp = (ngx_resolver_node_t *) temp;
1698
+
1699
+ p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen, rn_temp->nlen)
1700
+ < 0) ? &temp->left : &temp->right;
1701
+ }
1702
+
1703
+ if (*p == sentinel) {
1704
+ break;
1705
+ }
1706
+
1707
+ temp = *p;
1708
+ }
1709
+
1710
+ *p = node;
1711
+ node->parent = temp;
1712
+ node->left = sentinel;
1713
+ node->right = sentinel;
1714
+ ngx_rbt_red(node);
1715
+ }
1716
+
1717
+
1718
+ static ngx_int_t
1719
+ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
1720
+ {
1721
+ u_char *p, *s;
1722
+ size_t len, nlen;
1723
+ ngx_uint_t ident;
1724
+ ngx_resolver_qs_t *qs;
1725
+ ngx_resolver_query_t *query;
1726
+
1727
+ nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
1728
+
1729
+ len = sizeof(ngx_resolver_query_t) + nlen + sizeof(ngx_resolver_qs_t);
1730
+
1731
+ p = ngx_resolver_alloc(ctx->resolver, len);
1732
+ if (p == NULL) {
1733
+ return NGX_ERROR;
1734
+ }
1735
+
1736
+ rn->qlen = (u_short) len;
1737
+ rn->query = p;
1738
+
1739
+ query = (ngx_resolver_query_t *) p;
1740
+
1741
+ ident = ngx_random();
1742
+
1743
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
1744
+ "resolve: \"%V\" %i", &ctx->name, ident & 0xffff);
1745
+
1746
+ query->ident_hi = (u_char) ((ident >> 8) & 0xff);
1747
+ query->ident_lo = (u_char) (ident & 0xff);
1748
+
1749
+ /* recursion query */
1750
+ query->flags_hi = 1; query->flags_lo = 0;
1751
+
1752
+ /* one question */
1753
+ query->nqs_hi = 0; query->nqs_lo = 1;
1754
+ query->nan_hi = 0; query->nan_lo = 0;
1755
+ query->nns_hi = 0; query->nns_lo = 0;
1756
+ query->nar_hi = 0; query->nar_lo = 0;
1757
+
1758
+ p += sizeof(ngx_resolver_query_t) + nlen;
1759
+
1760
+ qs = (ngx_resolver_qs_t *) p;
1761
+
1762
+ /* query type */
1763
+ qs->type_hi = 0; qs->type_lo = (u_char) ctx->type;
1764
+
1765
+ /* IP query class */
1766
+ qs->class_hi = 0; qs->class_lo = 1;
1767
+
1768
+ /* convert "www.example.com" to "\3www\7example\3com\0" */
1769
+
1770
+ len = 0;
1771
+ p--;
1772
+ *p-- = '\0';
1773
+
1774
+ for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
1775
+ if (*s != '.') {
1776
+ *p = *s;
1777
+ len++;
1778
+
1779
+ } else {
1780
+ if (len == 0) {
1781
+ return NGX_DECLINED;
1782
+ }
1783
+
1784
+ *p = (u_char) len;
1785
+ len = 0;
1786
+ }
1787
+
1788
+ p--;
1789
+ }
1790
+
1791
+ *p = (u_char) len;
1792
+
1793
+ return NGX_OK;
1794
+ }
1795
+
1796
+
1797
+ /* AF_INET only */
1798
+
1799
+ static ngx_int_t
1800
+ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
1801
+ {
1802
+ u_char *p, *d;
1803
+ size_t len;
1804
+ ngx_int_t n;
1805
+ ngx_uint_t ident;
1806
+ ngx_resolver_query_t *query;
1807
+
1808
+ len = sizeof(ngx_resolver_query_t)
1809
+ + sizeof(".255.255.255.255.in-addr.arpa.") - 1
1810
+ + sizeof(ngx_resolver_qs_t);
1811
+
1812
+ p = ngx_resolver_alloc(ctx->resolver, len);
1813
+ if (p == NULL) {
1814
+ return NGX_ERROR;
1815
+ }
1816
+
1817
+ rn->query = p;
1818
+ query = (ngx_resolver_query_t *) p;
1819
+
1820
+ ident = ngx_random();
1821
+
1822
+ query->ident_hi = (u_char) ((ident >> 8) & 0xff);
1823
+ query->ident_lo = (u_char) (ident & 0xff);
1824
+
1825
+ /* recursion query */
1826
+ query->flags_hi = 1; query->flags_lo = 0;
1827
+
1828
+ /* one question */
1829
+ query->nqs_hi = 0; query->nqs_lo = 1;
1830
+ query->nan_hi = 0; query->nan_lo = 0;
1831
+ query->nns_hi = 0; query->nns_lo = 0;
1832
+ query->nar_hi = 0; query->nar_lo = 0;
1833
+
1834
+ p += sizeof(ngx_resolver_query_t);
1835
+
1836
+ for (n = 0; n < 32; n += 8) {
1837
+ d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff);
1838
+ *p = (u_char) (d - &p[1]);
1839
+ p = d;
1840
+ }
1841
+
1842
+ /* query type "PTR", IP query class */
1843
+ ngx_memcpy(p, "\7in-addr\4arpa\0\0\14\0\1", 18);
1844
+
1845
+ rn->qlen = (u_short)
1846
+ (p + sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t)
1847
+ - rn->query);
1848
+
1849
+ return NGX_OK;
1850
+ }
1851
+
1852
+
1853
+ static ngx_int_t
1854
+ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
1855
+ u_char *last)
1856
+ {
1857
+ char *err;
1858
+ u_char *p, *dst;
1859
+ ssize_t len;
1860
+ ngx_uint_t i, n;
1861
+
1862
+ p = src;
1863
+ len = -1;
1864
+
1865
+ /*
1866
+ * compression pointers allow to create endless loop, so we set limit;
1867
+ * 128 pointers should be enough to store 255-byte name
1868
+ */
1869
+
1870
+ for (i = 0; i < 128; i++) {
1871
+ n = *p++;
1872
+
1873
+ if (n == 0) {
1874
+ goto done;
1875
+ }
1876
+
1877
+ if (n & 0xc0) {
1878
+ n = ((n & 0x3f) << 8) + *p;
1879
+ p = &buf[n];
1880
+
1881
+ } else {
1882
+ len += 1 + n;
1883
+ p = &p[n];
1884
+ }
1885
+
1886
+ if (p >= last) {
1887
+ err = "name is out of response";
1888
+ goto invalid;
1889
+ }
1890
+ }
1891
+
1892
+ err = "compression pointers loop";
1893
+
1894
+ invalid:
1895
+
1896
+ ngx_log_error(r->log_level, r->log, 0, err);
1897
+
1898
+ return NGX_ERROR;
1899
+
1900
+ done:
1901
+
1902
+ if (name == NULL) {
1903
+ return NGX_OK;
1904
+ }
1905
+
1906
+ if (len == -1) {
1907
+ name->len = 0;
1908
+ name->data = NULL;
1909
+ return NGX_OK;
1910
+ }
1911
+
1912
+ dst = ngx_resolver_alloc(r, len);
1913
+ if (dst == NULL) {
1914
+ return NGX_ERROR;
1915
+ }
1916
+
1917
+ name->data = dst;
1918
+
1919
+ n = *src++;
1920
+
1921
+ for ( ;; ) {
1922
+ if (n & 0xc0) {
1923
+ n = ((n & 0x3f) << 8) + *src;
1924
+ src = &buf[n];
1925
+
1926
+ n = *src++;
1927
+
1928
+ } else {
1929
+ ngx_memcpy(dst, src, n);
1930
+ dst += n;
1931
+ src += n;
1932
+
1933
+ n = *src++;
1934
+
1935
+ if (n != 0) {
1936
+ *dst++ = '.';
1937
+ }
1938
+ }
1939
+
1940
+ if (n == 0) {
1941
+ name->len = dst - name->data;
1942
+ return NGX_OK;
1943
+ }
1944
+ }
1945
+ }
1946
+
1947
+
1948
+ static void
1949
+ ngx_resolver_timeout_handler(ngx_event_t *ev)
1950
+ {
1951
+ ngx_resolver_ctx_t *ctx;
1952
+
1953
+ ctx = ev->data;
1954
+
1955
+ ctx->state = NGX_RESOLVE_TIMEDOUT;
1956
+
1957
+ ctx->handler(ctx);
1958
+ }
1959
+
1960
+
1961
+ static void
1962
+ ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
1963
+ {
1964
+ /* lock alloc mutex */
1965
+
1966
+ if (rn->query) {
1967
+ ngx_resolver_free_locked(r, rn->query);
1968
+ }
1969
+
1970
+ if (rn->name) {
1971
+ ngx_resolver_free_locked(r, rn->name);
1972
+ }
1973
+
1974
+ if (rn->cnlen) {
1975
+ ngx_resolver_free_locked(r, rn->u.cname);
1976
+ }
1977
+
1978
+ if (rn->naddrs > 1) {
1979
+ ngx_resolver_free_locked(r, rn->u.addrs);
1980
+ }
1981
+
1982
+ ngx_resolver_free_locked(r, rn);
1983
+
1984
+ /* unlock alloc mutex */
1985
+ }
1986
+
1987
+
1988
+ static void *
1989
+ ngx_resolver_alloc(ngx_resolver_t *r, size_t size)
1990
+ {
1991
+ u_char *p;
1992
+
1993
+ /* lock alloc mutex */
1994
+
1995
+ p = ngx_alloc(size, r->log);
1996
+
1997
+ /* unlock alloc mutex */
1998
+
1999
+ return p;
2000
+ }
2001
+
2002
+
2003
+ static void *
2004
+ ngx_resolver_calloc(ngx_resolver_t *r, size_t size)
2005
+ {
2006
+ u_char *p;
2007
+
2008
+ p = ngx_resolver_alloc(r, size);
2009
+
2010
+ if (p) {
2011
+ ngx_memzero(p, size);
2012
+ }
2013
+
2014
+ return p;
2015
+ }
2016
+
2017
+
2018
+ static void
2019
+ ngx_resolver_free(ngx_resolver_t *r, void *p)
2020
+ {
2021
+ /* lock alloc mutex */
2022
+
2023
+ ngx_free(p);
2024
+
2025
+ /* unlock alloc mutex */
2026
+ }
2027
+
2028
+
2029
+ static void
2030
+ ngx_resolver_free_locked(ngx_resolver_t *r, void *p)
2031
+ {
2032
+ ngx_free(p);
2033
+ }
2034
+
2035
+
2036
+ static void *
2037
+ ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
2038
+ {
2039
+ void *dst;
2040
+
2041
+ dst = ngx_resolver_alloc(r, size);
2042
+
2043
+ if (dst == NULL) {
2044
+ return dst;
2045
+ }
2046
+
2047
+ ngx_memcpy(dst, src, size);
2048
+
2049
+ return dst;
2050
+ }
2051
+
2052
+
2053
+ char *
2054
+ ngx_resolver_strerror(ngx_int_t err)
2055
+ {
2056
+ static char *errors[] = {
2057
+ "Format error", /* FORMERR */
2058
+ "Server failure", /* SERVFAIL */
2059
+ "Host not found", /* NXDOMAIN */
2060
+ "Unimplemented", /* NOTIMP */
2061
+ "Operation refused" /* REFUSED */
2062
+ };
2063
+
2064
+ if (err > 0 && err < 6) {
2065
+ return errors[err - 1];
2066
+ }
2067
+
2068
+ if (err == NGX_RESOLVE_TIMEDOUT) {
2069
+ return "Operation timed out";
2070
+ }
2071
+
2072
+ return "Unknown error";
2073
+ }
2074
+
2075
+
2076
+ static u_char *
2077
+ ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
2078
+ {
2079
+ u_char *p;
2080
+ ngx_udp_connection_t *uc;
2081
+
2082
+ p = buf;
2083
+
2084
+ if (log->action) {
2085
+ p = ngx_snprintf(buf, len, " while %s", log->action);
2086
+ len -= p - buf;
2087
+ }
2088
+
2089
+ uc = log->data;
2090
+
2091
+ if (uc) {
2092
+ p = ngx_snprintf(p, len, ", resolver: %V", &uc->server);
2093
+ }
2094
+
2095
+ return p;
2096
+ }
2097
+
2098
+
2099
+ ngx_int_t
2100
+ ngx_udp_connect(ngx_udp_connection_t *uc)
2101
+ {
2102
+ int rc;
2103
+ ngx_int_t event;
2104
+ ngx_event_t *rev, *wev;
2105
+ ngx_socket_t s;
2106
+ ngx_connection_t *c;
2107
+
2108
+ s = ngx_socket(AF_INET, SOCK_DGRAM, 0);
2109
+
2110
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s);
2111
+
2112
+ if (s == -1) {
2113
+ ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
2114
+ ngx_socket_n " failed");
2115
+ return NGX_ERROR;
2116
+ }
2117
+
2118
+ c = ngx_get_connection(s, &uc->log);
2119
+
2120
+ if (c == NULL) {
2121
+ if (ngx_close_socket(s) == -1) {
2122
+ ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
2123
+ ngx_close_socket_n "failed");
2124
+ }
2125
+
2126
+ return NGX_ERROR;
2127
+ }
2128
+
2129
+ if (ngx_nonblocking(s) == -1) {
2130
+ ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
2131
+ ngx_nonblocking_n " failed");
2132
+
2133
+ ngx_free_connection(c);
2134
+
2135
+ if (ngx_close_socket(s) == -1) {
2136
+ ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
2137
+ ngx_close_socket_n " failed");
2138
+ }
2139
+
2140
+ return NGX_ERROR;
2141
+ }
2142
+
2143
+ rev = c->read;
2144
+ wev = c->write;
2145
+
2146
+ rev->log = &uc->log;
2147
+ wev->log = &uc->log;
2148
+
2149
+ uc->connection = c;
2150
+
2151
+ c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
2152
+
2153
+ #if (NGX_THREADS)
2154
+
2155
+ /* TODO: lock event when call completion handler */
2156
+
2157
+ rev->lock = &c->lock;
2158
+ wev->lock = &c->lock;
2159
+ rev->own_lock = &c->lock;
2160
+ wev->own_lock = &c->lock;
2161
+
2162
+ #endif
2163
+
2164
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
2165
+ "connect to %V, fd:%d #%d", &uc->server, s, c->number);
2166
+
2167
+ rc = connect(s, uc->sockaddr, uc->socklen);
2168
+
2169
+ /* TODO: aio, iocp */
2170
+
2171
+ if (rc == -1) {
2172
+ ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
2173
+ "connect() failed");
2174
+
2175
+ return NGX_ERROR;
2176
+ }
2177
+
2178
+ /* UDP sockets are always ready to write */
2179
+ wev->ready = 1;
2180
+
2181
+ if (ngx_add_event) {
2182
+
2183
+ event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ?
2184
+ /* kqueue, epoll */ NGX_CLEAR_EVENT:
2185
+ /* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
2186
+ /* eventport event type has no meaning: oneshot only */
2187
+
2188
+ if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
2189
+ return NGX_ERROR;
2190
+ }
2191
+
2192
+ } else {
2193
+ /* rtsig */
2194
+
2195
+ if (ngx_add_conn(c) == NGX_ERROR) {
2196
+ return NGX_ERROR;
2197
+ }
2198
+ }
2199
+
2200
+ return NGX_OK;
2201
+ }