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);