Mercurial > hg > nginx-vendor-0-5
comparison src/core/ngx_connection.c @ 112:408f195b3482 NGINX_0_3_3
nginx 0.3.3
*) Change: the "bl" and "af" parameters of the "listen" directive was
renamed to the "backlog" and "accept_filter".
*) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
directive.
*) Change: the "$msec" log parameter does not require now the
additional the gettimeofday() system call.
*) Feature: the -t switch now tests the "listen" directives.
*) Bugfix: if the invalid address was specified in the "listen"
directive, then after the -HUP signal nginx left an open socket in
the CLOSED state.
*) Bugfix: the mime type may be incorrectly set to default value for
index file with variable in the name; bug appeared in 0.3.0.
*) Feature: the "timer_resolution" directive.
*) Feature: the millisecond "$upstream_response_time" log parameter.
*) Bugfix: a temporary file with client request body now is removed
just after the response header was transferred to a client.
*) Bugfix: OpenSSL 0.9.6 compatibility.
*) Bugfix: the SSL certificate and key file paths could not be relative.
*) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
the ngx_imap_ssl_module.
*) Bugfix: the "ssl_protocols" directive allowed to specify the single
protocol only.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 00:00:00 +0400 |
parents | dad2fe8ecf08 |
children | ebca9c35e3a6 |
comparison
equal
deleted
inserted
replaced
111:a175b609c76d | 112:408f195b3482 |
---|---|
64 { | 64 { |
65 size_t len; | 65 size_t len; |
66 ngx_uint_t i; | 66 ngx_uint_t i; |
67 ngx_listening_t *ls; | 67 ngx_listening_t *ls; |
68 struct sockaddr_in *sin; | 68 struct sockaddr_in *sin; |
69 socklen_t olen; | |
69 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | 70 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) |
70 ngx_err_t err; | 71 ngx_err_t err; |
71 socklen_t aflen; | |
72 struct accept_filter_arg af; | 72 struct accept_filter_arg af; |
73 #endif | 73 #endif |
74 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | 74 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) |
75 socklen_t tlen; | |
76 int timeout; | 75 int timeout; |
77 #endif | 76 #endif |
78 | 77 |
79 ls = cycle->listening.elts; | 78 ls = cycle->listening.elts; |
80 for (i = 0; i < cycle->listening.nelts; i++) { | 79 for (i = 0; i < cycle->listening.nelts; i++) { |
124 ntohs(sin->sin_port)) | 123 ntohs(sin->sin_port)) |
125 - ls[i].addr_text.data; | 124 - ls[i].addr_text.data; |
126 | 125 |
127 ls[i].backlog = -1; | 126 ls[i].backlog = -1; |
128 | 127 |
128 olen = sizeof(int); | |
129 | |
130 if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf, | |
131 &olen) | |
132 == -1) | |
133 { | |
134 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, | |
135 "getsockopt(SO_RCVBUF) %V failed, ignored", | |
136 &ls[i].addr_text); | |
137 | |
138 ls[i].rcvbuf = -1; | |
139 } | |
140 | |
141 olen = sizeof(int); | |
142 | |
143 if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf, | |
144 &olen) | |
145 == -1) | |
146 { | |
147 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, | |
148 "getsockopt(SO_SNDBUF) %V failed, ignored", | |
149 &ls[i].addr_text); | |
150 | |
151 ls[i].sndbuf = -1; | |
152 } | |
153 | |
129 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | 154 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) |
130 | 155 |
131 ngx_memzero(&af, sizeof(struct accept_filter_arg)); | 156 ngx_memzero(&af, sizeof(struct accept_filter_arg)); |
132 aflen = sizeof(struct accept_filter_arg); | 157 olen = sizeof(struct accept_filter_arg); |
133 | 158 |
134 if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &aflen) | 159 if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen) |
135 == -1) | 160 == -1) |
136 { | 161 { |
137 err = ngx_errno; | 162 err = ngx_errno; |
138 | 163 |
139 if (err == NGX_EINVAL) { | 164 if (err == NGX_EINVAL) { |
144 "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored", | 169 "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored", |
145 &ls[i].addr_text); | 170 &ls[i].addr_text); |
146 continue; | 171 continue; |
147 } | 172 } |
148 | 173 |
149 if (aflen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') { | 174 if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') { |
150 continue; | 175 continue; |
151 } | 176 } |
152 | 177 |
153 ls[i].accept_filter = ngx_palloc(cycle->pool, 16); | 178 ls[i].accept_filter = ngx_palloc(cycle->pool, 16); |
154 if (ls[i].accept_filter == NULL) { | 179 if (ls[i].accept_filter == NULL) { |
160 #endif | 185 #endif |
161 | 186 |
162 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | 187 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) |
163 | 188 |
164 timeout = 0; | 189 timeout = 0; |
165 tlen = sizeof(int); | 190 olen = sizeof(int); |
166 | 191 |
167 if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &tlen) | 192 if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen) |
168 == -1) | 193 == -1) |
169 { | 194 { |
170 ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno, | 195 ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno, |
171 "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored", | 196 "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored", |
172 &ls[i].addr_text); | 197 &ls[i].addr_text); |
186 | 211 |
187 | 212 |
188 ngx_int_t | 213 ngx_int_t |
189 ngx_open_listening_sockets(ngx_cycle_t *cycle) | 214 ngx_open_listening_sockets(ngx_cycle_t *cycle) |
190 { | 215 { |
191 ngx_uint_t tries, failed, reuseaddr, i; | 216 int reuseaddr; |
217 ngx_uint_t i, tries, failed; | |
192 ngx_err_t err; | 218 ngx_err_t err; |
193 ngx_log_t *log; | 219 ngx_log_t *log; |
194 ngx_socket_t s; | 220 ngx_socket_t s; |
195 ngx_listening_t *ls; | 221 ngx_listening_t *ls; |
196 | 222 |
199 failed = 0; | 225 failed = 0; |
200 #endif | 226 #endif |
201 | 227 |
202 log = cycle->log; | 228 log = cycle->log; |
203 | 229 |
204 /* TODO: tries configurable */ | 230 /* TODO: configurable try number */ |
205 | 231 |
206 for (tries = /* STUB */ 5; tries; tries--) { | 232 for (tries = 5 ; tries; tries--) { |
207 failed = 0; | 233 failed = 0; |
208 | 234 |
209 /* for each listening socket */ | 235 /* for each listening socket */ |
210 | 236 |
211 ls = cycle->listening.elts; | 237 ls = cycle->listening.elts; |
234 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | 260 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, |
235 ngx_socket_n " %V failed", &ls[i].addr_text); | 261 ngx_socket_n " %V failed", &ls[i].addr_text); |
236 return NGX_ERROR; | 262 return NGX_ERROR; |
237 } | 263 } |
238 | 264 |
239 #if (NGX_WIN32) | |
240 | |
241 /* | |
242 * Winsock assignes a socket number divisible by 4 | |
243 * so to find a connection we divide a socket number by 4. | |
244 */ | |
245 | |
246 if (s % 4) { | |
247 ngx_log_error(NGX_LOG_EMERG, log, 0, | |
248 ngx_socket_n " created socket %d", s); | |
249 return NGX_ERROR; | |
250 } | |
251 #endif | |
252 | |
253 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, | 265 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, |
254 (const void *) &reuseaddr, sizeof(int)) == -1) { | 266 (const void *) &reuseaddr, sizeof(int)) |
267 == -1) | |
268 { | |
255 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | 269 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, |
256 "setsockopt(SO_REUSEADDR) %V failed", | 270 "setsockopt(SO_REUSEADDR) %V failed", |
257 &ls[i].addr_text); | 271 &ls[i].addr_text); |
272 | |
273 if (ngx_close_socket(s) == -1) | |
274 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
275 ngx_close_socket_n " %V failed", | |
276 &ls[i].addr_text); | |
277 | |
258 return NGX_ERROR; | 278 return NGX_ERROR; |
259 } | 279 } |
260 | 280 |
261 /* TODO: close on exit */ | 281 /* TODO: close on exit */ |
262 | 282 |
263 if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { | 283 if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { |
264 if (ngx_nonblocking(s) == -1) { | 284 if (ngx_nonblocking(s) == -1) { |
265 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | 285 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, |
266 ngx_nonblocking_n " %V failed", | 286 ngx_nonblocking_n " %V failed", |
267 &ls[i].addr_text); | 287 &ls[i].addr_text); |
288 | |
289 if (ngx_close_socket(s) == -1) | |
290 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
291 ngx_close_socket_n " %V failed", | |
292 &ls[i].addr_text); | |
293 | |
268 return NGX_ERROR; | 294 return NGX_ERROR; |
269 } | 295 } |
270 } | 296 } |
271 | 297 |
272 #if 0 | |
273 if (ls[i].nonblocking) { | |
274 if (ngx_nonblocking(s) == -1) { | |
275 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
276 ngx_nonblocking_n " %V failed", | |
277 &ls[i].addr_text); | |
278 return NGX_ERROR; | |
279 } | |
280 } | |
281 #endif | |
282 | |
283 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { | 298 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { |
284 err = ngx_socket_errno; | 299 err = ngx_socket_errno; |
300 | |
301 if (err == NGX_EADDRINUSE && ngx_test_config) { | |
302 continue; | |
303 } | |
304 | |
285 ngx_log_error(NGX_LOG_EMERG, log, err, | 305 ngx_log_error(NGX_LOG_EMERG, log, err, |
286 "bind() to %V failed", &ls[i].addr_text); | 306 "bind() to %V failed", &ls[i].addr_text); |
287 | |
288 if (err != NGX_EADDRINUSE) | |
289 return NGX_ERROR; | |
290 | 307 |
291 if (ngx_close_socket(s) == -1) | 308 if (ngx_close_socket(s) == -1) |
292 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | 309 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, |
293 ngx_close_socket_n " %V failed", | 310 ngx_close_socket_n " %V failed", |
294 &ls[i].addr_text); | 311 &ls[i].addr_text); |
295 | 312 |
313 if (err != NGX_EADDRINUSE) { | |
314 return NGX_ERROR; | |
315 } | |
316 | |
296 failed = 1; | 317 failed = 1; |
318 | |
297 continue; | 319 continue; |
298 } | 320 } |
299 | 321 |
300 if (listen(s, ls[i].backlog) == -1) { | 322 ls[i].listen = 1; |
301 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
302 "listen() to %V failed", &ls[i].addr_text); | |
303 return NGX_ERROR; | |
304 } | |
305 | |
306 /* TODO: deferred accept */ | |
307 | 323 |
308 ls[i].fd = s; | 324 ls[i].fd = s; |
309 } | 325 } |
310 | 326 |
311 if (!failed) | 327 if (!failed) { |
312 break; | 328 break; |
329 } | |
313 | 330 |
314 /* TODO: delay configurable */ | 331 /* TODO: delay configurable */ |
315 | 332 |
316 ngx_log_error(NGX_LOG_NOTICE, log, 0, | 333 ngx_log_error(NGX_LOG_NOTICE, log, 0, |
317 "try again to bind() after 500ms"); | 334 "try again to bind() after 500ms"); |
335 | |
318 ngx_msleep(500); | 336 ngx_msleep(500); |
319 } | 337 } |
320 | 338 |
321 if (failed) { | 339 if (failed) { |
322 ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()"); | 340 ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()"); |
326 return NGX_OK; | 344 return NGX_OK; |
327 } | 345 } |
328 | 346 |
329 | 347 |
330 void | 348 void |
349 ngx_configure_listening_socket(ngx_cycle_t *cycle) | |
350 { | |
351 ngx_uint_t i; | |
352 ngx_listening_t *ls; | |
353 | |
354 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) | |
355 struct accept_filter_arg af; | |
356 #endif | |
357 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) | |
358 int timeout; | |
359 #endif | |
360 | |
361 ls = cycle->listening.elts; | |
362 for (i = 0; i < cycle->listening.nelts; i++) { | |
363 | |
364 if (ls[i].rcvbuf != -1) { | |
365 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, | |
366 (const void *) &ls[i].rcvbuf, sizeof(int)) | |
367 == -1) | |
368 { | |
369 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, | |
370 "setsockopt(SO_RCVBUF) %V failed, ignored", | |
371 &ls[i].addr_text); | |
372 return; | |
373 } | |
374 } | |
375 | |
376 if (ls[i].sndbuf != -1) { | |
377 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, | |
378 (const void *) &ls[i].sndbuf, sizeof(int)) | |
379 == -1) | |
380 { | |
381 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, | |
382 "setsockopt(SO_SNDBUF) %V failed, ignored", | |
383 &ls[i].addr_text); | |
384 return; | |
385 } | |
386 } | |
387 | |
388 if (ls[i].listen) { | |
389 if (listen(ls[i].fd, ls[i].backlog) == -1) { | |
390 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, | |
391 "changing the listen() backlog to %d " | |
392 "for %V failed, ignored", | |
393 &ls[i].addr_text, ls[i].backlog); | |
394 } | |
395 } | |
396 | |
397 /* | |
398 * setting deferred mode should be last operation on socket, | |
399 * because code may prematurely continue cycle on failure | |
400 */ | |
401 | |
402 #if (NGX_HAVE_DEFERRED_ACCEPT) | |
403 | |
404 #ifdef SO_ACCEPTFILTER | |
405 | |
406 if (ls->delete_deferred) { | |
407 if (setsockopt(ls->fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0) == -1) | |
408 { | |
409 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
410 "setsockopt(SO_ACCEPTFILTER, NULL) " | |
411 "for %V failed, ignored", | |
412 &ls->addr_text); | |
413 | |
414 if (ls->accept_filter) { | |
415 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
416 "could not change the accept filter " | |
417 "to \"%s\" for %V, ignored", | |
418 ls->accept_filter, &ls->addr_text); | |
419 } | |
420 | |
421 continue; | |
422 } | |
423 | |
424 ls->deferred_accept = 0; | |
425 } | |
426 | |
427 if (ls->add_deferred) { | |
428 ngx_memzero(&af, sizeof(struct accept_filter_arg)); | |
429 (void) ngx_cpystrn((u_char *) af.af_name, | |
430 (u_char *) ls->accept_filter, 16); | |
431 | |
432 if (setsockopt(ls->fd, SOL_SOCKET, SO_ACCEPTFILTER, | |
433 &af, sizeof(struct accept_filter_arg)) | |
434 == -1) | |
435 { | |
436 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
437 "setsockopt(SO_ACCEPTFILTER, \"%s\") " | |
438 " for %V failed, ignored", | |
439 ls->accept_filter, &ls->addr_text); | |
440 continue; | |
441 } | |
442 | |
443 ls->deferred_accept = 1; | |
444 } | |
445 | |
446 #endif | |
447 | |
448 #ifdef TCP_DEFER_ACCEPT | |
449 | |
450 if (ls->add_deferred || ls->delete_deferred) { | |
451 | |
452 if (ls->add_deferred) { | |
453 timeout = (int) (ls->post_accept_timeout / 1000); | |
454 | |
455 } else { | |
456 timeout = 0; | |
457 } | |
458 | |
459 if (setsockopt(ls->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, | |
460 &timeout, sizeof(int)) | |
461 == -1) | |
462 { | |
463 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
464 "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, " | |
465 "ignored", | |
466 timeout, &ls->addr_text); | |
467 | |
468 continue; | |
469 } | |
470 } | |
471 | |
472 if (ls->add_deferred) { | |
473 ls->deferred_accept = 1; | |
474 } | |
475 | |
476 #endif | |
477 | |
478 #endif /* NGX_HAVE_DEFERRED_ACCEPT */ | |
479 } | |
480 | |
481 return; | |
482 } | |
483 | |
484 | |
485 void | |
331 ngx_close_listening_sockets(ngx_cycle_t *cycle) | 486 ngx_close_listening_sockets(ngx_cycle_t *cycle) |
332 { | 487 { |
333 ngx_uint_t i; | 488 ngx_uint_t i; |
334 ngx_listening_t *ls; | 489 ngx_listening_t *ls; |
335 ngx_connection_t *c; | 490 ngx_connection_t *c; |
358 } | 513 } |
359 | 514 |
360 ngx_free_connection(c); | 515 ngx_free_connection(c); |
361 | 516 |
362 c->fd = (ngx_socket_t) -1; | 517 c->fd = (ngx_socket_t) -1; |
518 | |
519 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
520 "close listening %V #%d ", &ls[i].addr_text, ls[i].fd); | |
363 | 521 |
364 if (ngx_close_socket(ls[i].fd) == -1) { | 522 if (ngx_close_socket(ls[i].fd) == -1) { |
365 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, | 523 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, |
366 ngx_close_socket_n " %V failed", &ls[i].addr_text); | 524 ngx_close_socket_n " %V failed", &ls[i].addr_text); |
367 } | 525 } |
493 * we have to clean the connection information before the closing | 651 * we have to clean the connection information before the closing |
494 * because another thread may reopen the same file descriptor | 652 * because another thread may reopen the same file descriptor |
495 * before we clean the connection | 653 * before we clean the connection |
496 */ | 654 */ |
497 | 655 |
498 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { | 656 ngx_mutex_lock(ngx_posted_events_mutex); |
499 | 657 |
500 if (c->read->prev) { | 658 if (c->read->prev) { |
501 ngx_delete_posted_event(c->read); | 659 ngx_delete_posted_event(c->read); |
502 } | 660 } |
503 | 661 |
504 if (c->write->prev) { | 662 if (c->write->prev) { |
505 ngx_delete_posted_event(c->write); | 663 ngx_delete_posted_event(c->write); |
506 } | 664 } |
507 | 665 |
508 c->read->closed = 1; | 666 c->read->closed = 1; |
509 c->write->closed = 1; | 667 c->write->closed = 1; |
510 | 668 |
511 if (c->single_connection) { | 669 if (c->single_connection) { |
512 ngx_unlock(&c->lock); | 670 ngx_unlock(&c->lock); |
513 c->read->locked = 0; | 671 c->read->locked = 0; |
514 c->write->locked = 0; | 672 c->write->locked = 0; |
515 } | 673 } |
516 | 674 |
517 ngx_mutex_unlock(ngx_posted_events_mutex); | 675 ngx_mutex_unlock(ngx_posted_events_mutex); |
518 } | |
519 | 676 |
520 #else | 677 #else |
521 | 678 |
522 if (c->read->prev) { | 679 if (c->read->prev) { |
523 ngx_delete_posted_event(c->read); | 680 ngx_delete_posted_event(c->read); |