comparison src/stream/ngx_stream_handler.c @ 6679:40e8ce405859

Stream: postpone session initialization under accept mutex. Previously, it was possible that some system calls could be invoked while holding the accept mutex. This is clearly wrong as it prevents incoming connections from being accepted as quickly as possible.
author Dmitry Volyntsev <xeioex@nginx.com>
date Tue, 06 Sep 2016 21:28:13 +0300
parents 0125b151c9a5
children 7357abd1fa8c
comparison
equal deleted inserted replaced
6678:0125b151c9a5 6679:40e8ce405859
11 #include <ngx_stream.h> 11 #include <ngx_stream.h>
12 12
13 13
14 static void ngx_stream_close_connection(ngx_connection_t *c); 14 static void ngx_stream_close_connection(ngx_connection_t *c);
15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); 15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len);
16 static void ngx_stream_init_session_handler(ngx_event_t *rev);
16 static void ngx_stream_init_session(ngx_connection_t *c); 17 static void ngx_stream_init_session(ngx_connection_t *c);
17 18
18 #if (NGX_STREAM_SSL) 19 #if (NGX_STREAM_SSL)
19 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); 20 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
20 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); 21 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c);
22 23
23 24
24 void 25 void
25 ngx_stream_init_connection(ngx_connection_t *c) 26 ngx_stream_init_connection(ngx_connection_t *c)
26 { 27 {
27 int tcp_nodelay;
28 u_char text[NGX_SOCKADDR_STRLEN]; 28 u_char text[NGX_SOCKADDR_STRLEN];
29 size_t len; 29 size_t len;
30 ngx_int_t rc;
31 ngx_uint_t i; 30 ngx_uint_t i;
32 ngx_time_t *tp; 31 ngx_time_t *tp;
32 ngx_event_t *rev;
33 struct sockaddr *sa; 33 struct sockaddr *sa;
34 ngx_stream_port_t *port; 34 ngx_stream_port_t *port;
35 struct sockaddr_in *sin; 35 struct sockaddr_in *sin;
36 ngx_stream_in_addr_t *addr; 36 ngx_stream_in_addr_t *addr;
37 ngx_stream_session_t *s; 37 ngx_stream_session_t *s;
128 128
129 s->signature = NGX_STREAM_MODULE; 129 s->signature = NGX_STREAM_MODULE;
130 s->main_conf = addr_conf->ctx->main_conf; 130 s->main_conf = addr_conf->ctx->main_conf;
131 s->srv_conf = addr_conf->ctx->srv_conf; 131 s->srv_conf = addr_conf->ctx->srv_conf;
132 132
133 #if (NGX_STREAM_SSL)
134 s->ssl = addr_conf->ssl;
135 #endif
136
133 s->connection = c; 137 s->connection = c;
134 c->data = s; 138 c->data = s;
135 139
136 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); 140 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
137 141
162 166
163 tp = ngx_timeofday(); 167 tp = ngx_timeofday();
164 s->start_sec = tp->sec; 168 s->start_sec = tp->sec;
165 s->start_msec = tp->msec; 169 s->start_msec = tp->msec;
166 170
171 rev = c->read;
172 rev->handler = ngx_stream_init_session_handler;
173
174 if (ngx_use_accept_mutex) {
175 ngx_post_event(rev, &ngx_posted_events);
176 return;
177 }
178
179 rev->handler(rev);
180 }
181
182
183 static void
184 ngx_stream_init_session_handler(ngx_event_t *rev)
185 {
186 int tcp_nodelay;
187 ngx_int_t rc;
188 ngx_connection_t *c;
189 ngx_stream_session_t *s;
190 ngx_stream_core_srv_conf_t *cscf;
191 ngx_stream_core_main_conf_t *cmcf;
192
193 c = rev->data;
194 s = c->data;
195
196 c->log->action = "initializing session";
197
198 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
199
167 if (cmcf->limit_conn_handler) { 200 if (cmcf->limit_conn_handler) {
168 rc = cmcf->limit_conn_handler(s); 201 rc = cmcf->limit_conn_handler(s);
169 202
170 if (rc == NGX_ERROR) { 203 if (rc == NGX_ERROR) {
171 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); 204 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
189 if (rc == NGX_ABORT) { 222 if (rc == NGX_ABORT) {
190 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); 223 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN);
191 return; 224 return;
192 } 225 }
193 } 226 }
227
228 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
194 229
195 if (c->type == SOCK_STREAM 230 if (c->type == SOCK_STREAM
196 && cscf->tcp_nodelay 231 && cscf->tcp_nodelay
197 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) 232 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
198 { 233 {
217 { 252 {
218 ngx_stream_ssl_conf_t *sslcf; 253 ngx_stream_ssl_conf_t *sslcf;
219 254
220 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); 255 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
221 256
222 if (addr_conf->ssl) { 257 if (s->ssl) {
223 c->log->action = "SSL handshaking"; 258 c->log->action = "SSL handshaking";
224 259
225 if (sslcf->ssl.ctx == NULL) { 260 if (sslcf->ssl.ctx == NULL) {
226 ngx_log_error(NGX_LOG_ERR, c->log, 0, 261 ngx_log_error(NGX_LOG_ERR, c->log, 0,
227 "no \"ssl_certificate\" is defined " 262 "no \"ssl_certificate\" is defined "