1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev#include <ngx_event.h>
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyev
13e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
14e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all);
15e18a033bSKonstantin Ananyevstatic void ngx_close_accepted_connection(ngx_connection_t *c);
16e18a033bSKonstantin Ananyev#if (NGX_DEBUG)
17e18a033bSKonstantin Ananyevstatic void ngx_debug_accepted_connection(ngx_event_conf_t *ecf,
18e18a033bSKonstantin Ananyev    ngx_connection_t *c);
19e18a033bSKonstantin Ananyev#endif
20e18a033bSKonstantin Ananyev
21e18a033bSKonstantin Ananyev
22e18a033bSKonstantin Ananyevvoid
23e18a033bSKonstantin Ananyevngx_event_accept(ngx_event_t *ev)
24e18a033bSKonstantin Ananyev{
25e18a033bSKonstantin Ananyev    socklen_t          socklen;
26e18a033bSKonstantin Ananyev    ngx_err_t          err;
27e18a033bSKonstantin Ananyev    ngx_log_t         *log;
28e18a033bSKonstantin Ananyev    ngx_uint_t         level;
29e18a033bSKonstantin Ananyev    ngx_socket_t       s;
30e18a033bSKonstantin Ananyev    ngx_event_t       *rev, *wev;
31e18a033bSKonstantin Ananyev    ngx_sockaddr_t     sa;
32e18a033bSKonstantin Ananyev    ngx_listening_t   *ls;
33e18a033bSKonstantin Ananyev    ngx_connection_t  *c, *lc;
34e18a033bSKonstantin Ananyev    ngx_event_conf_t  *ecf;
35e18a033bSKonstantin Ananyev#if (NGX_HAVE_ACCEPT4)
36e18a033bSKonstantin Ananyev    static ngx_uint_t  use_accept4 = 1;
37e18a033bSKonstantin Ananyev#endif
38e18a033bSKonstantin Ananyev
39e18a033bSKonstantin Ananyev    if (ev->timedout) {
40e18a033bSKonstantin Ananyev        if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
41e18a033bSKonstantin Ananyev            return;
42e18a033bSKonstantin Ananyev        }
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev        ev->timedout = 0;
45e18a033bSKonstantin Ananyev    }
46e18a033bSKonstantin Ananyev
47e18a033bSKonstantin Ananyev    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
48e18a033bSKonstantin Ananyev
49e18a033bSKonstantin Ananyev    if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
50e18a033bSKonstantin Ananyev        ev->available = ecf->multi_accept;
51e18a033bSKonstantin Ananyev    }
52e18a033bSKonstantin Ananyev
53e18a033bSKonstantin Ananyev    lc = ev->data;
54e18a033bSKonstantin Ananyev    ls = lc->listening;
55e18a033bSKonstantin Ananyev    ev->ready = 0;
56e18a033bSKonstantin Ananyev
57e18a033bSKonstantin Ananyev    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
58e18a033bSKonstantin Ananyev                   "accept on %V, ready: %d", &ls->addr_text, ev->available);
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev    do {
61e18a033bSKonstantin Ananyev        socklen = sizeof(ngx_sockaddr_t);
62e18a033bSKonstantin Ananyev
63e18a033bSKonstantin Ananyev#if (NGX_HAVE_ACCEPT4)
64e18a033bSKonstantin Ananyev        if (use_accept4) {
65e18a033bSKonstantin Ananyev            s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK);
66e18a033bSKonstantin Ananyev        } else {
67e18a033bSKonstantin Ananyev            s = accept(lc->fd, &sa.sockaddr, &socklen);
68e18a033bSKonstantin Ananyev        }
69e18a033bSKonstantin Ananyev#else
70e18a033bSKonstantin Ananyev        s = accept(lc->fd, &sa.sockaddr, &socklen);
71e18a033bSKonstantin Ananyev#endif
72e18a033bSKonstantin Ananyev
73e18a033bSKonstantin Ananyev        if (s == (ngx_socket_t) -1) {
74e18a033bSKonstantin Ananyev            err = ngx_socket_errno;
75e18a033bSKonstantin Ananyev
76e18a033bSKonstantin Ananyev            if (err == NGX_EAGAIN) {
77e18a033bSKonstantin Ananyev                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
78e18a033bSKonstantin Ananyev                               "accept() not ready");
79e18a033bSKonstantin Ananyev                return;
80e18a033bSKonstantin Ananyev            }
81e18a033bSKonstantin Ananyev
82e18a033bSKonstantin Ananyev            level = NGX_LOG_ALERT;
83e18a033bSKonstantin Ananyev
84e18a033bSKonstantin Ananyev            if (err == NGX_ECONNABORTED) {
85e18a033bSKonstantin Ananyev                level = NGX_LOG_ERR;
86e18a033bSKonstantin Ananyev
87e18a033bSKonstantin Ananyev            } else if (err == NGX_EMFILE || err == NGX_ENFILE) {
88e18a033bSKonstantin Ananyev                level = NGX_LOG_CRIT;
89e18a033bSKonstantin Ananyev            }
90e18a033bSKonstantin Ananyev
91e18a033bSKonstantin Ananyev#if (NGX_HAVE_ACCEPT4)
92e18a033bSKonstantin Ananyev            ngx_log_error(level, ev->log, err,
93e18a033bSKonstantin Ananyev                          use_accept4 ? "accept4() failed" : "accept() failed");
94e18a033bSKonstantin Ananyev
95e18a033bSKonstantin Ananyev            if (use_accept4 && err == NGX_ENOSYS) {
96e18a033bSKonstantin Ananyev                use_accept4 = 0;
97e18a033bSKonstantin Ananyev                ngx_inherited_nonblocking = 0;
98e18a033bSKonstantin Ananyev                continue;
99e18a033bSKonstantin Ananyev            }
100e18a033bSKonstantin Ananyev#else
101e18a033bSKonstantin Ananyev            ngx_log_error(level, ev->log, err, "accept() failed");
102e18a033bSKonstantin Ananyev#endif
103e18a033bSKonstantin Ananyev
104e18a033bSKonstantin Ananyev            if (err == NGX_ECONNABORTED) {
105e18a033bSKonstantin Ananyev                if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
106e18a033bSKonstantin Ananyev                    ev->available--;
107e18a033bSKonstantin Ananyev                }
108e18a033bSKonstantin Ananyev
109e18a033bSKonstantin Ananyev                if (ev->available) {
110e18a033bSKonstantin Ananyev                    continue;
111e18a033bSKonstantin Ananyev                }
112e18a033bSKonstantin Ananyev            }
113e18a033bSKonstantin Ananyev
114e18a033bSKonstantin Ananyev            if (err == NGX_EMFILE || err == NGX_ENFILE) {
115e18a033bSKonstantin Ananyev                if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle, 1)
116e18a033bSKonstantin Ananyev                    != NGX_OK)
117e18a033bSKonstantin Ananyev                {
118e18a033bSKonstantin Ananyev                    return;
119e18a033bSKonstantin Ananyev                }
120e18a033bSKonstantin Ananyev
121e18a033bSKonstantin Ananyev                if (ngx_use_accept_mutex) {
122e18a033bSKonstantin Ananyev                    if (ngx_accept_mutex_held) {
123e18a033bSKonstantin Ananyev                        ngx_shmtx_unlock(&ngx_accept_mutex);
124e18a033bSKonstantin Ananyev                        ngx_accept_mutex_held = 0;
125e18a033bSKonstantin Ananyev                    }
126e18a033bSKonstantin Ananyev
127e18a033bSKonstantin Ananyev                    ngx_accept_disabled = 1;
128e18a033bSKonstantin Ananyev
129e18a033bSKonstantin Ananyev                } else {
130e18a033bSKonstantin Ananyev                    ngx_add_timer(ev, ecf->accept_mutex_delay);
131e18a033bSKonstantin Ananyev                }
132e18a033bSKonstantin Ananyev            }
133e18a033bSKonstantin Ananyev
134e18a033bSKonstantin Ananyev            return;
135e18a033bSKonstantin Ananyev        }
136e18a033bSKonstantin Ananyev
137e18a033bSKonstantin Ananyev#if (NGX_STAT_STUB)
138e18a033bSKonstantin Ananyev        (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
139e18a033bSKonstantin Ananyev#endif
140e18a033bSKonstantin Ananyev
141e18a033bSKonstantin Ananyev        ngx_accept_disabled = ngx_cycle->connection_n / 8
142e18a033bSKonstantin Ananyev                              - ngx_cycle->free_connection_n;
143e18a033bSKonstantin Ananyev
144e18a033bSKonstantin Ananyev        c = ngx_get_connection(s, ev->log);
145e18a033bSKonstantin Ananyev
146e18a033bSKonstantin Ananyev        if (c == NULL) {
147e18a033bSKonstantin Ananyev            if (ngx_close_socket(s) == -1) {
148e18a033bSKonstantin Ananyev                ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
149e18a033bSKonstantin Ananyev                              ngx_close_socket_n " failed");
150e18a033bSKonstantin Ananyev            }
151e18a033bSKonstantin Ananyev
152e18a033bSKonstantin Ananyev            return;
153e18a033bSKonstantin Ananyev        }
154e18a033bSKonstantin Ananyev
155e18a033bSKonstantin Ananyev        c->type = SOCK_STREAM;
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyev#if (NGX_STAT_STUB)
158e18a033bSKonstantin Ananyev        (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
159e18a033bSKonstantin Ananyev#endif
160e18a033bSKonstantin Ananyev
161e18a033bSKonstantin Ananyev        c->pool = ngx_create_pool(ls->pool_size, ev->log);
162e18a033bSKonstantin Ananyev        if (c->pool == NULL) {
163e18a033bSKonstantin Ananyev            ngx_close_accepted_connection(c);
164e18a033bSKonstantin Ananyev            return;
165e18a033bSKonstantin Ananyev        }
166e18a033bSKonstantin Ananyev
167e18a033bSKonstantin Ananyev        c->sockaddr = ngx_palloc(c->pool, socklen);
168e18a033bSKonstantin Ananyev        if (c->sockaddr == NULL) {
169e18a033bSKonstantin Ananyev            ngx_close_accepted_connection(c);
170e18a033bSKonstantin Ananyev            return;
171e18a033bSKonstantin Ananyev        }
172e18a033bSKonstantin Ananyev
173e18a033bSKonstantin Ananyev        ngx_memcpy(c->sockaddr, &sa, socklen);
174e18a033bSKonstantin Ananyev
175e18a033bSKonstantin Ananyev        log = ngx_palloc(c->pool, sizeof(ngx_log_t));
176e18a033bSKonstantin Ananyev        if (log == NULL) {
177e18a033bSKonstantin Ananyev            ngx_close_accepted_connection(c);
178e18a033bSKonstantin Ananyev            return;
179e18a033bSKonstantin Ananyev        }
180e18a033bSKonstantin Ananyev
181e18a033bSKonstantin Ananyev        /* set a blocking mode for iocp and non-blocking mode for others */
182e18a033bSKonstantin Ananyev
183e18a033bSKonstantin Ananyev        if (ngx_inherited_nonblocking) {
184e18a033bSKonstantin Ananyev            if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
185e18a033bSKonstantin Ananyev                if (ngx_blocking(s) == -1) {
186e18a033bSKonstantin Ananyev                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
187e18a033bSKonstantin Ananyev                                  ngx_blocking_n " failed");
188e18a033bSKonstantin Ananyev                    ngx_close_accepted_connection(c);
189e18a033bSKonstantin Ananyev                    return;
190e18a033bSKonstantin Ananyev                }
191e18a033bSKonstantin Ananyev            }
192e18a033bSKonstantin Ananyev
193e18a033bSKonstantin Ananyev        } else {
194e18a033bSKonstantin Ananyev            if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
195e18a033bSKonstantin Ananyev                if (ngx_nonblocking(s) == -1) {
196e18a033bSKonstantin Ananyev                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
197e18a033bSKonstantin Ananyev                                  ngx_nonblocking_n " failed");
198e18a033bSKonstantin Ananyev                    ngx_close_accepted_connection(c);
199e18a033bSKonstantin Ananyev                    return;
200e18a033bSKonstantin Ananyev                }
201e18a033bSKonstantin Ananyev            }
202e18a033bSKonstantin Ananyev        }
203e18a033bSKonstantin Ananyev
204e18a033bSKonstantin Ananyev        *log = ls->log;
205e18a033bSKonstantin Ananyev
206e18a033bSKonstantin Ananyev        c->recv = ngx_recv;
207e18a033bSKonstantin Ananyev        c->send = ngx_send;
208e18a033bSKonstantin Ananyev        c->recv_chain = ngx_recv_chain;
209e18a033bSKonstantin Ananyev        c->send_chain = ngx_send_chain;
210e18a033bSKonstantin Ananyev
211e18a033bSKonstantin Ananyev        c->log = log;
212e18a033bSKonstantin Ananyev        c->pool->log = log;
213e18a033bSKonstantin Ananyev
214e18a033bSKonstantin Ananyev        c->socklen = socklen;
215e18a033bSKonstantin Ananyev        c->listening = ls;
216e18a033bSKonstantin Ananyev        c->local_sockaddr = ls->sockaddr;
217e18a033bSKonstantin Ananyev        c->local_socklen = ls->socklen;
218e18a033bSKonstantin Ananyev
219e18a033bSKonstantin Ananyev#if (NGX_HAVE_UNIX_DOMAIN)
220e18a033bSKonstantin Ananyev        if (c->sockaddr->sa_family == AF_UNIX) {
221e18a033bSKonstantin Ananyev            c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
222e18a033bSKonstantin Ananyev            c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
223e18a033bSKonstantin Ananyev#if (NGX_SOLARIS)
224e18a033bSKonstantin Ananyev            /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
225e18a033bSKonstantin Ananyev            c->sendfile = 0;
226e18a033bSKonstantin Ananyev#endif
227e18a033bSKonstantin Ananyev        }
228e18a033bSKonstantin Ananyev#endif
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyev        rev = c->read;
231e18a033bSKonstantin Ananyev        wev = c->write;
232e18a033bSKonstantin Ananyev
233e18a033bSKonstantin Ananyev        wev->ready = 1;
234e18a033bSKonstantin Ananyev
235e18a033bSKonstantin Ananyev        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
236e18a033bSKonstantin Ananyev            rev->ready = 1;
237e18a033bSKonstantin Ananyev        }
238e18a033bSKonstantin Ananyev
239e18a033bSKonstantin Ananyev        if (ev->deferred_accept) {
240e18a033bSKonstantin Ananyev            rev->ready = 1;
241e18a033bSKonstantin Ananyev#if (NGX_HAVE_KQUEUE)
242e18a033bSKonstantin Ananyev            rev->available = 1;
243e18a033bSKonstantin Ananyev#endif
244e18a033bSKonstantin Ananyev        }
245e18a033bSKonstantin Ananyev
246e18a033bSKonstantin Ananyev        rev->log = log;
247e18a033bSKonstantin Ananyev        wev->log = log;
248e18a033bSKonstantin Ananyev
249e18a033bSKonstantin Ananyev        /*
250e18a033bSKonstantin Ananyev         * TODO: MT: - ngx_atomic_fetch_add()
251e18a033bSKonstantin Ananyev         *             or protection by critical section or light mutex
252e18a033bSKonstantin Ananyev         *
253e18a033bSKonstantin Ananyev         * TODO: MP: - allocated in a shared memory
254e18a033bSKonstantin Ananyev         *           - ngx_atomic_fetch_add()
255e18a033bSKonstantin Ananyev         *             or protection by critical section or light mutex
256e18a033bSKonstantin Ananyev         */
257e18a033bSKonstantin Ananyev
258e18a033bSKonstantin Ananyev        c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
259e18a033bSKonstantin Ananyev
260e18a033bSKonstantin Ananyev#if (NGX_STAT_STUB)
261e18a033bSKonstantin Ananyev        (void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
262e18a033bSKonstantin Ananyev#endif
263e18a033bSKonstantin Ananyev
264e18a033bSKonstantin Ananyev        if (ls->addr_ntop) {
265e18a033bSKonstantin Ananyev            c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
266e18a033bSKonstantin Ananyev            if (c->addr_text.data == NULL) {
267e18a033bSKonstantin Ananyev                ngx_close_accepted_connection(c);
268e18a033bSKonstantin Ananyev                return;
269e18a033bSKonstantin Ananyev            }
270e18a033bSKonstantin Ananyev
271e18a033bSKonstantin Ananyev            c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
272e18a033bSKonstantin Ananyev                                             c->addr_text.data,
273e18a033bSKonstantin Ananyev                                             ls->addr_text_max_len, 0);
274e18a033bSKonstantin Ananyev            if (c->addr_text.len == 0) {
275e18a033bSKonstantin Ananyev                ngx_close_accepted_connection(c);
276e18a033bSKonstantin Ananyev                return;
277e18a033bSKonstantin Ananyev            }
278e18a033bSKonstantin Ananyev        }
279e18a033bSKonstantin Ananyev
280e18a033bSKonstantin Ananyev#if (NGX_DEBUG)
281e18a033bSKonstantin Ananyev        {
282e18a033bSKonstantin Ananyev        ngx_str_t  addr;
283e18a033bSKonstantin Ananyev        u_char     text[NGX_SOCKADDR_STRLEN];
284e18a033bSKonstantin Ananyev
285e18a033bSKonstantin Ananyev        ngx_debug_accepted_connection(ecf, c);
286e18a033bSKonstantin Ananyev
287e18a033bSKonstantin Ananyev        if (log->log_level & NGX_LOG_DEBUG_EVENT) {
288e18a033bSKonstantin Ananyev            addr.data = text;
289e18a033bSKonstantin Ananyev            addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
290e18a033bSKonstantin Ananyev                                     NGX_SOCKADDR_STRLEN, 1);
291e18a033bSKonstantin Ananyev
292e18a033bSKonstantin Ananyev            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
293e18a033bSKonstantin Ananyev                           "*%uA accept: %V fd:%d", c->number, &addr, s);
294e18a033bSKonstantin Ananyev        }
295e18a033bSKonstantin Ananyev
296e18a033bSKonstantin Ananyev        }
297e18a033bSKonstantin Ananyev#endif
298e18a033bSKonstantin Ananyev
299e18a033bSKonstantin Ananyev        if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
300e18a033bSKonstantin Ananyev            if (ngx_add_conn(c) == NGX_ERROR) {
301e18a033bSKonstantin Ananyev                ngx_close_accepted_connection(c);
302e18a033bSKonstantin Ananyev                return;
303e18a033bSKonstantin Ananyev            }
304e18a033bSKonstantin Ananyev        }
305e18a033bSKonstantin Ananyev
306e18a033bSKonstantin Ananyev        log->data = NULL;
307e18a033bSKonstantin Ananyev        log->handler = NULL;
308e18a033bSKonstantin Ananyev
309e18a033bSKonstantin Ananyev        ls->handler(c);
310e18a033bSKonstantin Ananyev
311e18a033bSKonstantin Ananyev        if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
312e18a033bSKonstantin Ananyev            ev->available--;
313e18a033bSKonstantin Ananyev        }
314e18a033bSKonstantin Ananyev
315e18a033bSKonstantin Ananyev    } while (ev->available);
316e18a033bSKonstantin Ananyev}
317e18a033bSKonstantin Ananyev
318e18a033bSKonstantin Ananyev
319e18a033bSKonstantin Ananyev#if !(NGX_WIN32)
320e18a033bSKonstantin Ananyev
321e18a033bSKonstantin Ananyevvoid
322e18a033bSKonstantin Ananyevngx_event_recvmsg(ngx_event_t *ev)
323e18a033bSKonstantin Ananyev{
324e18a033bSKonstantin Ananyev    ssize_t            n;
325e18a033bSKonstantin Ananyev    ngx_log_t         *log;
326e18a033bSKonstantin Ananyev    ngx_err_t          err;
327e18a033bSKonstantin Ananyev    ngx_event_t       *rev, *wev;
328e18a033bSKonstantin Ananyev    struct iovec       iov[1];
329e18a033bSKonstantin Ananyev    struct msghdr      msg;
330e18a033bSKonstantin Ananyev    ngx_sockaddr_t     sa;
331e18a033bSKonstantin Ananyev    ngx_listening_t   *ls;
332e18a033bSKonstantin Ananyev    ngx_event_conf_t  *ecf;
333e18a033bSKonstantin Ananyev    ngx_connection_t  *c, *lc;
334e18a033bSKonstantin Ananyev    static u_char      buffer[65535];
335e18a033bSKonstantin Ananyev
336e18a033bSKonstantin Ananyev#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
337e18a033bSKonstantin Ananyev
338e18a033bSKonstantin Ananyev#if (NGX_HAVE_IP_RECVDSTADDR)
339e18a033bSKonstantin Ananyev    u_char             msg_control[CMSG_SPACE(sizeof(struct in_addr))];
340e18a033bSKonstantin Ananyev#elif (NGX_HAVE_IP_PKTINFO)
341e18a033bSKonstantin Ananyev    u_char             msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))];
342e18a033bSKonstantin Ananyev#endif
343e18a033bSKonstantin Ananyev
344e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
345e18a033bSKonstantin Ananyev    u_char             msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
346e18a033bSKonstantin Ananyev#endif
347e18a033bSKonstantin Ananyev
348e18a033bSKonstantin Ananyev#endif
349e18a033bSKonstantin Ananyev
350e18a033bSKonstantin Ananyev    if (ev->timedout) {
351e18a033bSKonstantin Ananyev        if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
352e18a033bSKonstantin Ananyev            return;
353e18a033bSKonstantin Ananyev        }
354e18a033bSKonstantin Ananyev
355e18a033bSKonstantin Ananyev        ev->timedout = 0;
356e18a033bSKonstantin Ananyev    }
357e18a033bSKonstantin Ananyev
358e18a033bSKonstantin Ananyev    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
359e18a033bSKonstantin Ananyev
360e18a033bSKonstantin Ananyev    if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
361e18a033bSKonstantin Ananyev        ev->available = ecf->multi_accept;
362e18a033bSKonstantin Ananyev    }
363e18a033bSKonstantin Ananyev
364e18a033bSKonstantin Ananyev    lc = ev->data;
365e18a033bSKonstantin Ananyev    ls = lc->listening;
366e18a033bSKonstantin Ananyev    ev->ready = 0;
367e18a033bSKonstantin Ananyev
368e18a033bSKonstantin Ananyev    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
369e18a033bSKonstantin Ananyev                   "recvmsg on %V, ready: %d", &ls->addr_text, ev->available);
370e18a033bSKonstantin Ananyev
371e18a033bSKonstantin Ananyev    do {
372e18a033bSKonstantin Ananyev        ngx_memzero(&msg, sizeof(struct msghdr));
373e18a033bSKonstantin Ananyev
374e18a033bSKonstantin Ananyev        iov[0].iov_base = (void *) buffer;
375e18a033bSKonstantin Ananyev        iov[0].iov_len = sizeof(buffer);
376e18a033bSKonstantin Ananyev
377e18a033bSKonstantin Ananyev        msg.msg_name = &sa;
378e18a033bSKonstantin Ananyev        msg.msg_namelen = sizeof(ngx_sockaddr_t);
379e18a033bSKonstantin Ananyev        msg.msg_iov = iov;
380e18a033bSKonstantin Ananyev        msg.msg_iovlen = 1;
381e18a033bSKonstantin Ananyev
382e18a033bSKonstantin Ananyev#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
383e18a033bSKonstantin Ananyev
384e18a033bSKonstantin Ananyev        if (ls->wildcard) {
385e18a033bSKonstantin Ananyev
386e18a033bSKonstantin Ananyev#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO)
387e18a033bSKonstantin Ananyev            if (ls->sockaddr->sa_family == AF_INET) {
388e18a033bSKonstantin Ananyev                msg.msg_control = &msg_control;
389e18a033bSKonstantin Ananyev                msg.msg_controllen = sizeof(msg_control);
390e18a033bSKonstantin Ananyev            }
391e18a033bSKonstantin Ananyev#endif
392e18a033bSKonstantin Ananyev
393e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
394e18a033bSKonstantin Ananyev            if (ls->sockaddr->sa_family == AF_INET6) {
395e18a033bSKonstantin Ananyev                msg.msg_control = &msg_control6;
396e18a033bSKonstantin Ananyev                msg.msg_controllen = sizeof(msg_control6);
397e18a033bSKonstantin Ananyev            }
398e18a033bSKonstantin Ananyev#endif
399e18a033bSKonstantin Ananyev        }
400e18a033bSKonstantin Ananyev
401e18a033bSKonstantin Ananyev#endif
402e18a033bSKonstantin Ananyev
403e18a033bSKonstantin Ananyev        n = recvmsg(lc->fd, &msg, 0);
404e18a033bSKonstantin Ananyev
405e18a033bSKonstantin Ananyev        if (n == -1) {
406e18a033bSKonstantin Ananyev            err = ngx_socket_errno;
407e18a033bSKonstantin Ananyev
408e18a033bSKonstantin Ananyev            if (err == NGX_EAGAIN) {
409e18a033bSKonstantin Ananyev                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
410e18a033bSKonstantin Ananyev                               "recvmsg() not ready");
411e18a033bSKonstantin Ananyev                return;
412e18a033bSKonstantin Ananyev            }
413e18a033bSKonstantin Ananyev
414e18a033bSKonstantin Ananyev            ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed");
415e18a033bSKonstantin Ananyev
416e18a033bSKonstantin Ananyev            return;
417e18a033bSKonstantin Ananyev        }
418e18a033bSKonstantin Ananyev
419