1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10
11
12 ngx_os_io_t ngx_io;
13
14
15 ngx_listening_t *
16 ngx_listening_inet_stream_socket(ngx_conf_t *cf, in_addr_t addr, in_port_t port)
17 {
18 size_t len;
19 ngx_listening_t *ls;
20 struct sockaddr_in *sin;
21
22 ls = ngx_array_push(&cf->cycle->listening);
23 if (ls == NULL) {
24 return NULL;
25 }
26
27 ngx_memzero(ls, sizeof(ngx_listening_t));
28
29 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
30 if (sin == NULL) {
31 return NULL;
32 }
33
34 sin->sin_family = AF_INET;
35 sin->sin_addr.s_addr = addr;
36 sin->sin_port = htons(port);
37
38
39 ls->addr_text.data = ngx_palloc(cf->pool,
40 INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);
41 if (ls->addr_text.data == NULL) {
42 return NULL;
43 }
44
45 len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN);
46
47 ls->addr_text.len = ngx_sprintf(ls->addr_text.data + len, ":%d", port)
48 - ls->addr_text.data;
49
50 ls->fd = (ngx_socket_t) -1;
51 ls->family = AF_INET;
52 ls->type = SOCK_STREAM;
53 ls->sockaddr = (struct sockaddr *) sin;
54 ls->socklen = sizeof(struct sockaddr_in);
55 ls->addr = offsetof(struct sockaddr_in, sin_addr);
56 ls->addr_text_max_len = INET_ADDRSTRLEN;
57
58 return ls;
59 }
60
61
62 ngx_int_t
63 ngx_set_inherited_sockets(ngx_cycle_t *cycle)
64 {
65 size_t len;
66 ngx_uint_t i;
67 ngx_listening_t *ls;
68 struct sockaddr_in *sin;
69 socklen_t olen;
70 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
71 ngx_err_t err;
72 struct accept_filter_arg af;
73 #endif
74 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
75 int timeout;
76 #endif
77
78 ls = cycle->listening.elts;
79 for (i = 0; i < cycle->listening.nelts; i++) {
80
81 /* AF_INET only */
82
83 ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(struct sockaddr_in));
84 if (ls[i].sockaddr == NULL) {
85 return NGX_ERROR;
86 }
87
88 ls[i].socklen = sizeof(struct sockaddr_in);
89 if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
90 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
91 "getsockname() of the inherited "
92 "socket #%d failed", ls[i].fd);
93 ls[i].ignore = 1;
94 continue;
95 }
96
97 sin = (struct sockaddr_in *) ls[i].sockaddr;
98
99 if (sin->sin_family != AF_INET) {
100 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
101 "the inherited socket #%d has "
102 "unsupported family", ls[i].fd);
103 ls[i].ignore = 1;
104 continue;
105 }
106
107 ls[i].addr_text_max_len = INET_ADDRSTRLEN;
108
109 ls[i].addr_text.data = ngx_palloc(cycle->pool, INET_ADDRSTRLEN - 1
110 + sizeof(":65535") - 1);
111 if (ls[i].addr_text.data == NULL) {
112 return NGX_ERROR;
113 }
114
115 ls[i].family = sin->sin_family;
116 len = ngx_sock_ntop(ls[i].family, ls[i].sockaddr,
117 ls[i].addr_text.data, INET_ADDRSTRLEN);
118 if (len == 0) {
119 return NGX_ERROR;
120 }
121
122 ls[i].addr_text.len = ngx_sprintf(ls[i].addr_text.data + len, ":%d",
123 ntohs(sin->sin_port))
124 - ls[i].addr_text.data;
125
126 ls[i].backlog = NGX_LISTEN_BACKLOG;
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
154 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
155
156 ngx_memzero(&af, sizeof(struct accept_filter_arg));
157 olen = sizeof(struct accept_filter_arg);
158
159 if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
160 == -1)
161 {
162 err = ngx_errno;
163
164 if (err == NGX_EINVAL) {
165 continue;
166 }
167
168 ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
169 "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
170 &ls[i].addr_text);
171 continue;
172 }
173
174 if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
175 continue;
176 }
177
178 ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
179 if (ls[i].accept_filter == NULL) {
180 return NGX_ERROR;
181 }
182
183 (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
184 (u_char *) af.af_name, 16);
185 #endif
186
187 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
188
189 timeout = 0;
190 olen = sizeof(int);
191
192 if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
193 == -1)
194 {
195 ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
196 "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
197 &ls[i].addr_text);
198 continue;
199 }
200
201 if (olen < sizeof(int) || timeout == 0) {
202 continue;
203 }
204
205 ls[i].deferred_accept = 1;
206 #endif
207 }
208
209 return NGX_OK;
210 }
211
212
213 ngx_int_t
214 ngx_open_listening_sockets(ngx_cycle_t *cycle)
215 {
216 int reuseaddr;
217 ngx_uint_t i, tries, failed;
218 ngx_err_t err;
219 ngx_log_t *log;
220 ngx_socket_t s;
221 ngx_listening_t *ls;
222
223 reuseaddr = 1;
224 #if (NGX_SUPPRESS_WARN)
225 failed = 0;
226 #endif
227
228 log = cycle->log;
229
230 /* TODO: configurable try number */
231
232 for (tries = 5 ; tries; tries--) {
233 failed = 0;
234
235 /* for each listening socket */
236
237 ls = cycle->listening.elts;
238 for (i = 0; i < cycle->listening.nelts; i++) {
239
240 if (ls[i].ignore) {
241 continue;
242 }
243
244 if (ls[i].fd != -1) {
245 continue;
246 }
247
248 if (ls[i].inherited) {
249
250 /* TODO: close on exit */
251 /* TODO: nonblocking */
252 /* TODO: deferred accept */
253
254 continue;
255 }
256
257 s = ngx_socket(ls[i].family, ls[i].type, 0);
258
259 if (s == -1) {
260 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
261 ngx_socket_n " %V failed", &ls[i].addr_text);
262 return NGX_ERROR;
263 }
264
265 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
266 (const void *) &reuseaddr, sizeof(int))
267 == -1)
268 {
269 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
270 "setsockopt(SO_REUSEADDR) %V failed",
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 }
278
279 return NGX_ERROR;
280 }
281
282 /* TODO: close on exit */
283
284 if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
285 if (ngx_nonblocking(s) == -1) {
286 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
287 ngx_nonblocking_n " %V failed",
288 &ls[i].addr_text);
289
290 if (ngx_close_socket(s) == -1) {
291 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
292 ngx_close_socket_n " %V failed",
293 &ls[i].addr_text);
294 }
295
296 return NGX_ERROR;
297 }
298 }
299
300 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
301 "bind() %V #%d ", &ls[i].addr_text, s);
302
303 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
304 err = ngx_socket_errno;
305
306 if (err == NGX_EADDRINUSE && ngx_test_config) {
307 continue;
308 }
309
310 ngx_log_error(NGX_LOG_EMERG, log, err,
311 "bind() to %V failed", &ls[i].addr_text);
312
313 if (ngx_close_socket(s) == -1) {
314 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
315 ngx_close_socket_n " %V failed",
316 &ls[i].addr_text);
317 }
318
319 if (err != NGX_EADDRINUSE) {
320 return NGX_ERROR;
321 }
322
323 failed = 1;
324
325 continue;
326 }
327
328 if (listen(s, ls[i].backlog) == -1) {
329 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
330 "listen() to %V, backlog %d failed",
331 &ls[i].addr_text, ls[i].backlog);
332
333 if (ngx_close_socket(s) == -1) {
334 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
335 ngx_close_socket_n " %V failed",
336 &ls[i].addr_text);
337 }
338
339 return NGX_ERROR;
340 }
341
342 ls[i].listen = 1;
343
344 ls[i].fd = s;
345 }
346
347 if (!failed) {
348 break;
349 }
350
351 /* TODO: delay configurable */
352
353 ngx_log_error(NGX_LOG_NOTICE, log, 0,
354 "try again to bind() after 500ms");
355
356 ngx_msleep(500);
357 }
358
359 if (failed) {
360 ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
361 return NGX_ERROR;
362 }
363
364 return NGX_OK;
365 }
366
367
368 void
369 ngx_configure_listening_socket(ngx_cycle_t *cycle)
370 {
371 ngx_uint_t i;
372 ngx_listening_t *ls;
373
374 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
375 struct accept_filter_arg af;
376 #endif
377 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
378 int timeout;
379 #endif
380
381 ls = cycle->listening.elts;
382 for (i = 0; i < cycle->listening.nelts; i++) {
383
384 if (ls[i].rcvbuf != -1) {
385 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
386 (const void *) &ls[i].rcvbuf, sizeof(int))
387 == -1)
388 {
389 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
390 "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
391 ls[i].rcvbuf, &ls[i].addr_text);
392 }
393 }
394
395 if (ls[i].sndbuf != -1) {
396 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
397 (const void *) &ls[i].sndbuf, sizeof(int))
398 == -1)
399 {
400 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
401 "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
402 ls[i].sndbuf, &ls[i].addr_text);
403 }
404 }
405
406 #if 0
407 if (1) {
408 int tcp_nodelay = 1;
409
410 if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
411 (const void *) &tcp_nodelay, sizeof(int))
412 == -1)
413 {
414 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
415 "setsockopt(TCP_NODELAY) %V failed, ignored",
416 &ls[i].addr_text);
417 }
418 }
419 #endif
420
421 if (ls[i].listen) {
422
423 /* change backlog via listen() */
424
425 if (listen(ls[i].fd, ls[i].backlog) == -1) {
426 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
427 "listen() to %V, backlog %d failed, ignored",
428 &ls[i].addr_text, ls[i].backlog);
429 }
430 }
431
432 /*
433 * setting deferred mode should be last operation on socket,
434 * because code may prematurely continue cycle on failure
435 */
436
437 #if (NGX_HAVE_DEFERRED_ACCEPT)
438
439 #ifdef SO_ACCEPTFILTER
440
441 if (ls[i].delete_deferred) {
442 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
443 == -1)
444 {
445 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
446 "setsockopt(SO_ACCEPTFILTER, NULL) "
447 "for %V failed, ignored",
448 &ls[i].addr_text);
449
450 if (ls[i].accept_filter) {
451 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
452 "could not change the accept filter "
453 "to \"%s\" for %V, ignored",
454 ls[i].accept_filter, &ls[i].addr_text);
455 }
456
457 continue;
458 }
459
460 ls[i].deferred_accept = 0;
461 }
462
463 if (ls[i].add_deferred) {
464 ngx_memzero(&af, sizeof(struct accept_filter_arg));
465 (void) ngx_cpystrn((u_char *) af.af_name,
466 (u_char *) ls[i].accept_filter, 16);
467
468 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
469 &af, sizeof(struct accept_filter_arg))
470 == -1)
471 {
472 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
473 "setsockopt(SO_ACCEPTFILTER, \"%s\") "
474 " for %V failed, ignored",
475 ls[i].accept_filter, &ls[i].addr_text);
476 continue;
477 }
478
479 ls[i].deferred_accept = 1;
480 }
481
482 #endif
483
484 #ifdef TCP_DEFER_ACCEPT
485
486 if (ls[i].add_deferred || ls[i].delete_deferred) {
487
488 if (ls[i].add_deferred) {
489 timeout = (int) (ls[i].post_accept_timeout / 1000);
490
491 } else {
492 timeout = 0;
493 }
494
495 if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
496 &timeout, sizeof(int))
497 == -1)
498 {
499 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
500 "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
501 "ignored",
502 timeout, &ls[i].addr_text);
503
504 continue;
505 }
506 }
507
508 if (ls[i].add_deferred) {
509 ls[i].deferred_accept = 1;
510 }
511
512 #endif
513
514 #endif /* NGX_HAVE_DEFERRED_ACCEPT */
515 }
516
517 return;
518 }
519
520
521 void
522 ngx_close_listening_sockets(ngx_cycle_t *cycle)
523 {
524 ngx_uint_t i;
525 ngx_listening_t *ls;
526 ngx_connection_t *c;
527
528 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
529 return;
530 }
531
532 ngx_accept_mutex_held = 0;
533 ngx_use_accept_mutex = 0;
534
535 ls = cycle->listening.elts;
536 for (i = 0; i < cycle->listening.nelts; i++) {
537
538 c = ls[i].connection;
539
540 if (c->read->active) {
541 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
542 ngx_del_conn(c, NGX_CLOSE_EVENT);
543
544 } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
545
546 /*
547 * it seems that Linux-2.6.x OpenVZ sends events
548 * for closed shared listening sockets unless
549 * the events was explicity deleted
550 */
551
552 ngx_del_event(c->read, NGX_READ_EVENT, 0);
553
554 } else {
555 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
556 }
557 }
558
559 ngx_free_connection(c);
560
561 c->fd = (ngx_socket_t) -1;
562
563 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
564 "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
565
566 if (ngx_close_socket(ls[i].fd) == -1) {
567 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
568 ngx_close_socket_n " %V failed", &ls[i].addr_text);
569 }
570 }
571 }
572
573
574 ngx_connection_t *
575 ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
576 {
577 ngx_uint_t instance;
578 ngx_event_t *rev, *wev;
579 ngx_connection_t *c;
580
581 /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
582
583 if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
584 ngx_log_error(NGX_LOG_ALERT, log, 0,
585 "the new socket has number %d, "
586 "but only %ui files are available",
587 s, ngx_cycle->files_n);
588 return NULL;
589 }
590
591 /* ngx_mutex_lock */
592
593 c = ngx_cycle->free_connections;
594
595 if (c == NULL) {
596 ngx_log_error(NGX_LOG_ALERT, log, 0,
597 "%ui worker_connections is not enough",
598 ngx_cycle->connection_n);
599
600 /* ngx_mutex_unlock */
601
602 return NULL;
603 }
604
605 ngx_cycle->free_connections = c->data;
606 ngx_cycle->free_connection_n--;
607
608 /* ngx_mutex_unlock */
609
610 if (ngx_cycle->files) {
611 ngx_cycle->files[s] = c;
612 }
613
614 rev = c->read;
615 wev = c->write;
616
617 ngx_memzero(c, sizeof(ngx_connection_t));
618
619 c->read = rev;
620 c->write = wev;
621 c->fd = s;
622 c->log = log;
623
624 instance = rev->instance;
625
626 ngx_memzero(rev, sizeof(ngx_event_t));
627 ngx_memzero(wev, sizeof(ngx_event_t));
628
629 rev->instance = !instance;
630 wev->instance = !instance;
631
632 rev->index = NGX_INVALID_INDEX;
633 wev->index = NGX_INVALID_INDEX;
634
635 rev->data = c;
636 wev->data = c;
637
638 wev->write = 1;
639
640 return c;
641 }
642
643
644 void
645 ngx_free_connection(ngx_connection_t *c)
646 {
647 /* ngx_mutex_lock */
648
649 c->data = ngx_cycle->free_connections;
650 ngx_cycle->free_connections = c;
651 ngx_cycle->free_connection_n++;
652
653 /* ngx_mutex_unlock */
654
655 if (ngx_cycle->files) {
656 ngx_cycle->files[c->fd] = NULL;
657 }
658 }
659
660
661 void
662 ngx_close_connection(ngx_connection_t *c)
663 {
664 ngx_socket_t fd;
665
666 if (c->fd == -1) {
667 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
668 return;
669 }
670
671 if (c->read->timer_set) {
672 ngx_del_timer(c->read);
673 }
674
675 if (c->write->timer_set) {
676 ngx_del_timer(c->write);
677 }
678
679 if (ngx_del_conn) {
680 ngx_del_conn(c, NGX_CLOSE_EVENT);
681
682 } else {
683 if (c->read->active || c->read->disabled) {
684 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
685 }
686
687 if (c->write->active || c->write->disabled) {
688 ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
689 }
690 }
691
692 #if (NGX_THREADS)
693
694 /*
695 * we have to clean the connection information before the closing
696 * because another thread may reopen the same file descriptor
697 * before we clean the connection
698 */
699
700 ngx_mutex_lock(ngx_posted_events_mutex);
701
702 if (c->read->prev) {
703 ngx_delete_posted_event(c->read);
704 }
705
706 if (c->write->prev) {
707 ngx_delete_posted_event(c->write);
708 }
709
710 c->read->closed = 1;
711 c->write->closed = 1;
712
713 if (c->single_connection) {
714 ngx_unlock(&c->lock);
715 c->read->locked = 0;
716 c->write->locked = 0;
717 }
718
719 ngx_mutex_unlock(ngx_posted_events_mutex);
720
721 #else
722
723 if (c->read->prev) {
724 ngx_delete_posted_event(c->read);
725 }
726
727 if (c->write->prev) {
728 ngx_delete_posted_event(c->write);
729 }
730
731 c->read->closed = 1;
732 c->write->closed = 1;
733
734 #endif
735
736 ngx_free_connection(c);
737
738 fd = c->fd;
739 c->fd = (ngx_socket_t) -1;
740
741 if (ngx_close_socket(fd) == -1) {
742
743 /* we use ngx_cycle->log because c->log was in c->pool */
744
745 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
746 ngx_close_socket_n " %d failed", fd);
747 }
748 }
749
750
751 ngx_int_t
752 ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
753 {
754 ngx_uint_t level;
755
756 if (err == NGX_ECONNRESET
757 && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
758 {
759 return 0;
760 }
761
762 if (err == 0
763 || err == NGX_ECONNRESET
764 #if !(NGX_WIN32)
765 || err == NGX_EPIPE
766 #endif
767 || err == NGX_ENOTCONN
768 || err == NGX_ETIMEDOUT
769 || err == NGX_ECONNREFUSED
770 || err == NGX_ENETDOWN
771 || err == NGX_ENETUNREACH
772 || err == NGX_EHOSTDOWN
773 || err == NGX_EHOSTUNREACH)
774 {
775 switch (c->log_error) {
776
777 case NGX_ERROR_IGNORE_ECONNRESET:
778 case NGX_ERROR_INFO:
779 level = NGX_LOG_INFO;
780 break;
781
782 case NGX_ERROR_ERR:
783 level = NGX_LOG_ERR;
784 break;
785
786 default:
787 level = NGX_LOG_CRIT;
788 }
789
790 } else {
791 level = NGX_LOG_CRIT;
792 }
793
794 ngx_log_error(level, c->log, err, text);
795
796 return NGX_ERROR;
797 }
798
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.