xref: /unit/src/nxt_controller.c (revision 20)
1*20Sigor@sysoev.ru 
2*20Sigor@sysoev.ru /*
3*20Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
4*20Sigor@sysoev.ru  * Copyright (C) Valentin V. Bartenev
5*20Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
6*20Sigor@sysoev.ru  */
7*20Sigor@sysoev.ru 
8*20Sigor@sysoev.ru #include <nxt_main.h>
9*20Sigor@sysoev.ru #include <nxt_runtime.h>
10*20Sigor@sysoev.ru #include <nxt_master_process.h>
11*20Sigor@sysoev.ru 
12*20Sigor@sysoev.ru 
13*20Sigor@sysoev.ru static void nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data);
14*20Sigor@sysoev.ru static void nxt_controller_conn_read(nxt_task_t *task, void *obj, void *data);
15*20Sigor@sysoev.ru static nxt_msec_t nxt_controller_conn_timeout_value(nxt_event_conn_t *c,
16*20Sigor@sysoev.ru     uintptr_t data);
17*20Sigor@sysoev.ru static void nxt_controller_conn_read_error(nxt_task_t *task, void *obj,
18*20Sigor@sysoev.ru     void *data);
19*20Sigor@sysoev.ru static void nxt_controller_conn_read_timeout(nxt_task_t *task, void *obj,
20*20Sigor@sysoev.ru     void *data);
21*20Sigor@sysoev.ru static void nxt_controller_conn_close(nxt_task_t *task, void *obj, void *data);
22*20Sigor@sysoev.ru static void nxt_controller_conn_free(nxt_task_t *task, void *obj, void *data);
23*20Sigor@sysoev.ru 
24*20Sigor@sysoev.ru 
25*20Sigor@sysoev.ru static const nxt_event_conn_state_t  nxt_controller_conn_read_state;
26*20Sigor@sysoev.ru static const nxt_event_conn_state_t  nxt_controller_conn_close_state;
27*20Sigor@sysoev.ru 
28*20Sigor@sysoev.ru 
29*20Sigor@sysoev.ru nxt_int_t
30*20Sigor@sysoev.ru nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt)
31*20Sigor@sysoev.ru {
32*20Sigor@sysoev.ru     if (nxt_event_conn_listen(task, rt->controller_socket) != NXT_OK) {
33*20Sigor@sysoev.ru         return NXT_ERROR;
34*20Sigor@sysoev.ru     }
35*20Sigor@sysoev.ru 
36*20Sigor@sysoev.ru     return NXT_OK;
37*20Sigor@sysoev.ru }
38*20Sigor@sysoev.ru 
39*20Sigor@sysoev.ru 
40*20Sigor@sysoev.ru nxt_int_t
41*20Sigor@sysoev.ru nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt)
42*20Sigor@sysoev.ru {
43*20Sigor@sysoev.ru     nxt_sockaddr_t       *sa;
44*20Sigor@sysoev.ru     nxt_listen_socket_t  *ls;
45*20Sigor@sysoev.ru 
46*20Sigor@sysoev.ru     sa = rt->controller_listen;
47*20Sigor@sysoev.ru 
48*20Sigor@sysoev.ru     if (rt->controller_listen == NULL) {
49*20Sigor@sysoev.ru         sa = nxt_sockaddr_alloc(rt->mem_pool, sizeof(struct sockaddr_in),
50*20Sigor@sysoev.ru                                 NXT_INET_ADDR_STR_LEN);
51*20Sigor@sysoev.ru         if (sa == NULL) {
52*20Sigor@sysoev.ru             return NXT_ERROR;
53*20Sigor@sysoev.ru         }
54*20Sigor@sysoev.ru 
55*20Sigor@sysoev.ru         sa->type = SOCK_STREAM;
56*20Sigor@sysoev.ru         sa->u.sockaddr_in.sin_family = AF_INET;
57*20Sigor@sysoev.ru         sa->u.sockaddr_in.sin_port = htons(8443);
58*20Sigor@sysoev.ru 
59*20Sigor@sysoev.ru         nxt_sockaddr_text(sa);
60*20Sigor@sysoev.ru 
61*20Sigor@sysoev.ru         rt->controller_listen = sa;
62*20Sigor@sysoev.ru     }
63*20Sigor@sysoev.ru 
64*20Sigor@sysoev.ru     ls = nxt_mem_alloc(rt->mem_pool, sizeof(nxt_listen_socket_t));
65*20Sigor@sysoev.ru     if (ls == NULL) {
66*20Sigor@sysoev.ru         return NXT_ERROR;
67*20Sigor@sysoev.ru     }
68*20Sigor@sysoev.ru 
69*20Sigor@sysoev.ru     ls->sockaddr = nxt_sockaddr_create(rt->mem_pool, &sa->u.sockaddr,
70*20Sigor@sysoev.ru                                        sa->socklen, sa->length);
71*20Sigor@sysoev.ru     if (ls->sockaddr == NULL) {
72*20Sigor@sysoev.ru         return NXT_ERROR;
73*20Sigor@sysoev.ru     }
74*20Sigor@sysoev.ru 
75*20Sigor@sysoev.ru     ls->sockaddr->type = sa->type;
76*20Sigor@sysoev.ru 
77*20Sigor@sysoev.ru     nxt_sockaddr_text(ls->sockaddr);
78*20Sigor@sysoev.ru 
79*20Sigor@sysoev.ru     ls->socket = -1;
80*20Sigor@sysoev.ru     ls->backlog = NXT_LISTEN_BACKLOG;
81*20Sigor@sysoev.ru     ls->read_after_accept = 1;
82*20Sigor@sysoev.ru     ls->flags = NXT_NONBLOCK;
83*20Sigor@sysoev.ru 
84*20Sigor@sysoev.ru #if 0
85*20Sigor@sysoev.ru     /* STUB */
86*20Sigor@sysoev.ru     wq = nxt_mem_zalloc(cf->mem_pool, sizeof(nxt_work_queue_t));
87*20Sigor@sysoev.ru     if (wq == NULL) {
88*20Sigor@sysoev.ru         return NXT_ERROR;
89*20Sigor@sysoev.ru     }
90*20Sigor@sysoev.ru     nxt_work_queue_name(wq, "listen");
91*20Sigor@sysoev.ru     /**/
92*20Sigor@sysoev.ru 
93*20Sigor@sysoev.ru     ls->work_queue = wq;
94*20Sigor@sysoev.ru #endif
95*20Sigor@sysoev.ru     ls->handler = nxt_controller_conn_init;
96*20Sigor@sysoev.ru 
97*20Sigor@sysoev.ru     /*
98*20Sigor@sysoev.ru      * Connection memory pool chunk size is tunned to
99*20Sigor@sysoev.ru      * allocate the most data in one mem_pool chunk.
100*20Sigor@sysoev.ru      */
101*20Sigor@sysoev.ru     ls->mem_pool_size = nxt_listen_socket_pool_min_size(ls)
102*20Sigor@sysoev.ru                         + sizeof(nxt_event_conn_proxy_t)
103*20Sigor@sysoev.ru                         + sizeof(nxt_event_conn_t)
104*20Sigor@sysoev.ru                         + 4 * sizeof(nxt_buf_t);
105*20Sigor@sysoev.ru 
106*20Sigor@sysoev.ru     if (nxt_listen_socket_create(task, ls, 0) != NXT_OK) {
107*20Sigor@sysoev.ru         return NXT_ERROR;
108*20Sigor@sysoev.ru     }
109*20Sigor@sysoev.ru 
110*20Sigor@sysoev.ru     rt->controller_socket = ls;
111*20Sigor@sysoev.ru 
112*20Sigor@sysoev.ru     return NXT_OK;
113*20Sigor@sysoev.ru }
114*20Sigor@sysoev.ru 
115*20Sigor@sysoev.ru 
116*20Sigor@sysoev.ru static void
117*20Sigor@sysoev.ru nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data)
118*20Sigor@sysoev.ru {
119*20Sigor@sysoev.ru     nxt_buf_t           *b;
120*20Sigor@sysoev.ru     nxt_event_conn_t    *c;
121*20Sigor@sysoev.ru     nxt_event_engine_t  *engine;
122*20Sigor@sysoev.ru 
123*20Sigor@sysoev.ru     c = obj;
124*20Sigor@sysoev.ru 
125*20Sigor@sysoev.ru     nxt_debug(task, "controller conn init fd:%d", c->socket.fd);
126*20Sigor@sysoev.ru 
127*20Sigor@sysoev.ru     b = nxt_buf_mem_alloc(c->mem_pool, 1024, 0);
128*20Sigor@sysoev.ru     if (nxt_slow_path(b == NULL)) {
129*20Sigor@sysoev.ru         nxt_controller_conn_free(task, c, NULL);
130*20Sigor@sysoev.ru         return;
131*20Sigor@sysoev.ru     }
132*20Sigor@sysoev.ru 
133*20Sigor@sysoev.ru     c->read = b;
134*20Sigor@sysoev.ru     c->socket.read_ready = 1;
135*20Sigor@sysoev.ru     c->read_state = &nxt_controller_conn_read_state;
136*20Sigor@sysoev.ru 
137*20Sigor@sysoev.ru     engine = task->thread->engine;
138*20Sigor@sysoev.ru     c->read_work_queue = &engine->read_work_queue;
139*20Sigor@sysoev.ru 
140*20Sigor@sysoev.ru     nxt_event_conn_read(engine, c);
141*20Sigor@sysoev.ru }
142*20Sigor@sysoev.ru 
143*20Sigor@sysoev.ru 
144*20Sigor@sysoev.ru static const nxt_event_conn_state_t  nxt_controller_conn_read_state
145*20Sigor@sysoev.ru     nxt_aligned(64) =
146*20Sigor@sysoev.ru {
147*20Sigor@sysoev.ru     NXT_EVENT_NO_BUF_PROCESS,
148*20Sigor@sysoev.ru     NXT_EVENT_TIMER_NO_AUTORESET,
149*20Sigor@sysoev.ru 
150*20Sigor@sysoev.ru     nxt_controller_conn_read,
151*20Sigor@sysoev.ru     nxt_controller_conn_close,
152*20Sigor@sysoev.ru     nxt_controller_conn_read_error,
153*20Sigor@sysoev.ru 
154*20Sigor@sysoev.ru     nxt_controller_conn_read_timeout,
155*20Sigor@sysoev.ru     nxt_controller_conn_timeout_value,
156*20Sigor@sysoev.ru     60 * 1000,
157*20Sigor@sysoev.ru };
158*20Sigor@sysoev.ru 
159*20Sigor@sysoev.ru 
160*20Sigor@sysoev.ru static void
161*20Sigor@sysoev.ru nxt_controller_conn_read(nxt_task_t *task, void *obj, void *data)
162*20Sigor@sysoev.ru {
163*20Sigor@sysoev.ru     nxt_event_conn_t  *c;
164*20Sigor@sysoev.ru 
165*20Sigor@sysoev.ru     c = obj;
166*20Sigor@sysoev.ru 
167*20Sigor@sysoev.ru     nxt_debug(task, "controller conn read");
168*20Sigor@sysoev.ru 
169*20Sigor@sysoev.ru     nxt_controller_conn_close(task, c, c->socket.data);
170*20Sigor@sysoev.ru }
171*20Sigor@sysoev.ru 
172*20Sigor@sysoev.ru 
173*20Sigor@sysoev.ru static nxt_msec_t
174*20Sigor@sysoev.ru nxt_controller_conn_timeout_value(nxt_event_conn_t *c, uintptr_t data)
175*20Sigor@sysoev.ru {
176*20Sigor@sysoev.ru     return (nxt_msec_t) data;
177*20Sigor@sysoev.ru }
178*20Sigor@sysoev.ru 
179*20Sigor@sysoev.ru 
180*20Sigor@sysoev.ru static void
181*20Sigor@sysoev.ru nxt_controller_conn_read_error(nxt_task_t *task, void *obj, void *data)
182*20Sigor@sysoev.ru {
183*20Sigor@sysoev.ru     nxt_event_conn_t  *c;
184*20Sigor@sysoev.ru 
185*20Sigor@sysoev.ru     c = obj;
186*20Sigor@sysoev.ru 
187*20Sigor@sysoev.ru     nxt_debug(task, "controller conn read error");
188*20Sigor@sysoev.ru 
189*20Sigor@sysoev.ru     nxt_controller_conn_close(task, c, c->socket.data);
190*20Sigor@sysoev.ru }
191*20Sigor@sysoev.ru 
192*20Sigor@sysoev.ru 
193*20Sigor@sysoev.ru static void
194*20Sigor@sysoev.ru nxt_controller_conn_read_timeout(nxt_task_t *task, void *obj, void *data)
195*20Sigor@sysoev.ru {
196*20Sigor@sysoev.ru     nxt_timer_t       *ev;
197*20Sigor@sysoev.ru     nxt_event_conn_t  *c;
198*20Sigor@sysoev.ru 
199*20Sigor@sysoev.ru     ev = obj;
200*20Sigor@sysoev.ru 
201*20Sigor@sysoev.ru     c = nxt_event_read_timer_conn(ev);
202*20Sigor@sysoev.ru     c->socket.timedout = 1;
203*20Sigor@sysoev.ru     c->socket.closed = 1;
204*20Sigor@sysoev.ru 
205*20Sigor@sysoev.ru     nxt_debug(task, "controller conn read timeout");
206*20Sigor@sysoev.ru 
207*20Sigor@sysoev.ru     nxt_controller_conn_close(task, c, c->socket.data);
208*20Sigor@sysoev.ru }
209*20Sigor@sysoev.ru 
210*20Sigor@sysoev.ru 
211*20Sigor@sysoev.ru static const nxt_event_conn_state_t  nxt_controller_conn_close_state
212*20Sigor@sysoev.ru     nxt_aligned(64) =
213*20Sigor@sysoev.ru {
214*20Sigor@sysoev.ru     NXT_EVENT_NO_BUF_PROCESS,
215*20Sigor@sysoev.ru     NXT_EVENT_TIMER_NO_AUTORESET,
216*20Sigor@sysoev.ru 
217*20Sigor@sysoev.ru     nxt_controller_conn_free,
218*20Sigor@sysoev.ru     NULL,
219*20Sigor@sysoev.ru     NULL,
220*20Sigor@sysoev.ru 
221*20Sigor@sysoev.ru     NULL,
222*20Sigor@sysoev.ru     NULL,
223*20Sigor@sysoev.ru     0,
224*20Sigor@sysoev.ru };
225*20Sigor@sysoev.ru 
226*20Sigor@sysoev.ru 
227*20Sigor@sysoev.ru static void
228*20Sigor@sysoev.ru nxt_controller_conn_close(nxt_task_t *task, void *obj, void *data)
229*20Sigor@sysoev.ru {
230*20Sigor@sysoev.ru     nxt_event_conn_t  *c;
231*20Sigor@sysoev.ru 
232*20Sigor@sysoev.ru     c = obj;
233*20Sigor@sysoev.ru 
234*20Sigor@sysoev.ru     nxt_debug(task, "controller conn close");
235*20Sigor@sysoev.ru 
236*20Sigor@sysoev.ru     c->write_state = &nxt_controller_conn_close_state;
237*20Sigor@sysoev.ru 
238*20Sigor@sysoev.ru     nxt_event_conn_close(task->thread->engine, c);
239*20Sigor@sysoev.ru }
240*20Sigor@sysoev.ru 
241*20Sigor@sysoev.ru 
242*20Sigor@sysoev.ru static void
243*20Sigor@sysoev.ru nxt_controller_conn_free(nxt_task_t *task, void *obj, void *data)
244*20Sigor@sysoev.ru {
245*20Sigor@sysoev.ru     nxt_event_conn_t  *c;
246*20Sigor@sysoev.ru 
247*20Sigor@sysoev.ru     c = obj;
248*20Sigor@sysoev.ru 
249*20Sigor@sysoev.ru     nxt_debug(task, "controller conn free");
250*20Sigor@sysoev.ru 
251*20Sigor@sysoev.ru     nxt_mem_pool_destroy(c->mem_pool);
252*20Sigor@sysoev.ru 
253*20Sigor@sysoev.ru     //nxt_free(c);
254*20Sigor@sysoev.ru }
255