comparison src/event/ngx_event_openssl.c @ 22:8b6db3bda591 NGINX_0_1_11

nginx 0.1.11 *) Feature: the worker_priority directive. *) Change: both tcp_nopush and tcp_nodelay directives affect the transferred response. *) Bugfix: nginx did not call initgroups(). Thanks to Andrew Sitnikov and Andrei Nigmatulin. *) Change: now the ngx_http_autoindex_module shows the file size in the bytes. *) Bugfix: the ngx_http_autoindex_module returned the 500 error if the broken symlink was in a directory. *) Bugfix: the files bigger than 4G could not be transferred using sendfile. *) Bugfix: if the backend was resolved to several backends and there was an error while the response waiting then process may got caught in an endless loop. *) Bugfix: the worker process may exit with the "unknown cycle" message when the /dev/poll method was used. *) Bugfix: "close() channel failed" errors. *) Bugfix: the autodetection of the "nobody" and "nogroup" groups. *) Bugfix: the send_lowat directive did not work on Linux. *) Bugfix: the segmentation fault occurred if there was no events section in configuration. *) Bugfix: nginx could not be built on OpenBSD. *) Bugfix: the double slashes in "://" in the URI were converted to ":/".
author Igor Sysoev <http://sysoev.ru>
date Thu, 02 Dec 2004 00:00:00 +0300
parents 6f8b0dc0f8dd
children 7ca9bdc82b3f
comparison
equal deleted inserted replaced
21:4eeb9cfef970 22:8b6db3bda591
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 10
11 11
12 static void ngx_ssl_write_handler(ngx_event_t *wev);
12 static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size); 13 static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
14 static void ngx_ssl_read_handler(ngx_event_t *rev);
13 15
14 16
15 ngx_int_t ngx_ssl_init(ngx_log_t *log) 17 ngx_int_t ngx_ssl_init(ngx_log_t *log)
16 { 18 {
17 SSL_library_init(); 19 SSL_library_init();
67 n = SSL_read(c->ssl->ssl, buf, size); 69 n = SSL_read(c->ssl->ssl, buf, size);
68 70
69 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 71 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
70 72
71 if (n > 0) { 73 if (n > 0) {
74 if (c->ssl->saved_write_handler) {
75
76 c->write->event_handler = c->ssl->saved_write_handler;
77 c->ssl->saved_write_handler = NULL;
78 c->write->ready = 1;
79
80 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
81 return NGX_ERROR;
82 }
83
84 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
85 return NGX_ERROR;
86 }
87
88 ngx_post_event(c->write);
89
90 ngx_mutex_unlock(ngx_posted_events_mutex);
91 }
92
72 return n; 93 return n;
73 } 94 }
74 95
75 if (!SSL_is_init_finished(c->ssl->ssl)) { 96 if (!SSL_is_init_finished(c->ssl->ssl)) {
76 handshake = " in SSL handshake"; 97 handshake = " in SSL handshake";
91 } 112 }
92 113
93 if (sslerr == SSL_ERROR_WANT_WRITE) { 114 if (sslerr == SSL_ERROR_WANT_WRITE) {
94 ngx_log_error(NGX_LOG_ALERT, c->log, err, 115 ngx_log_error(NGX_LOG_ALERT, c->log, err,
95 "SSL wants to write%s", handshake); 116 "SSL wants to write%s", handshake);
96 return NGX_ERROR; 117
97 #if 0 118 c->write->ready = 0;
98 return NGX_AGAIN; 119
99 #endif 120 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
121 return NGX_ERROR;
122 }
123
124 /*
125 * we do not set the timer because there is already the read event timer
126 */
127
128 if (c->ssl->saved_write_handler == NULL) {
129 c->ssl->saved_write_handler = c->write->event_handler;
130 c->write->event_handler = ngx_ssl_write_handler;
131 }
132
133 return NGX_AGAIN;
100 } 134 }
101 135
102 c->ssl->no_rcv_shut = 1; 136 c->ssl->no_rcv_shut = 1;
137 c->ssl->no_send_shut = 1;
103 138
104 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { 139 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
105 ngx_log_error(NGX_LOG_INFO, c->log, err, 140 ngx_log_error(NGX_LOG_INFO, c->log, err,
106 "client closed connection%s", handshake); 141 "client closed connection%s", handshake);
107 142
113 148
114 return NGX_ERROR; 149 return NGX_ERROR;
115 } 150 }
116 151
117 152
153 static void ngx_ssl_write_handler(ngx_event_t *wev)
154 {
155 ngx_connection_t *c;
156
157 c = wev->data;
158 c->read->event_handler(c->read);
159 }
160
161
118 /* 162 /*
119 * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer 163 * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
120 * before SSL_write() call to decrease a SSL overhead. 164 * before the SSL_write() call to decrease a SSL overhead.
121 * 165 *
122 * Besides for protocols such as HTTP it is possible to always buffer 166 * Besides for protocols such as HTTP it is possible to always buffer
123 * the output to decrease a SSL overhead some more. 167 * the output to decrease a SSL overhead some more.
124 */ 168 */
125 169
153 in->buf->pos += n; 197 in->buf->pos += n;
154 198
155 return in; 199 return in;
156 } 200 }
157 201
202
203 /* the maximum limit size is the maximum uint32_t value - the page size */
204
205 if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
206 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
207 }
208
209
158 send = 0; 210 send = 0;
159 flush = (in == NULL) ? 1 : 0; 211 flush = (in == NULL) ? 1 : 0;
160 212
161 for ( ;; ) { 213 for ( ;; ) {
162 214
250 n = SSL_write(c->ssl->ssl, data, size); 302 n = SSL_write(c->ssl->ssl, data, size);
251 303
252 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); 304 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
253 305
254 if (n > 0) { 306 if (n > 0) {
307 if (c->ssl->saved_read_handler) {
308
309 c->read->event_handler = c->ssl->saved_read_handler;
310 c->ssl->saved_read_handler = NULL;
311 c->read->ready = 1;
312
313 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
314 return NGX_ERROR;
315 }
316
317 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
318 return NGX_ERROR;
319 }
320
321 ngx_post_event(c->read);
322
323 ngx_mutex_unlock(ngx_posted_events_mutex);
324 }
325
255 return n; 326 return n;
256 } 327 }
257 328
258 sslerr = SSL_get_error(c->ssl->ssl, n); 329 sslerr = SSL_get_error(c->ssl->ssl, n);
259 330
275 handshake = ""; 346 handshake = "";
276 } 347 }
277 348
278 ngx_log_error(NGX_LOG_ALERT, c->log, err, 349 ngx_log_error(NGX_LOG_ALERT, c->log, err,
279 "SSL wants to read%s", handshake); 350 "SSL wants to read%s", handshake);
280 return NGX_ERROR; 351
281 #if 0 352 c->read->ready = 0;
282 return NGX_AGAIN; 353
283 #endif 354 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
355 return NGX_ERROR;
356 }
357
358 /*
359 * we do not set the timer because there is already
360 * the write event timer
361 */
362
363 if (c->ssl->saved_read_handler == NULL) {
364 c->ssl->saved_read_handler = c->read->event_handler;
365 c->read->event_handler = ngx_ssl_read_handler;
366 }
367
368 return NGX_AGAIN;
284 } 369 }
285 370
286 c->ssl->no_rcv_shut = 1; 371 c->ssl->no_rcv_shut = 1;
372 c->ssl->no_send_shut = 1;
287 373
288 ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed"); 374 ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed");
289 375
290 return NGX_ERROR; 376 return NGX_ERROR;
291 } 377 }
292 378
293 379
380 static void ngx_ssl_read_handler(ngx_event_t *rev)
381 {
382 ngx_connection_t *c;
383
384 c = rev->data;
385 c->write->event_handler(c->write);
386 }
387
388
294 ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) 389 ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
295 { 390 {
296 int n, sslerr; 391 int n, sslerr, mode;
297 ngx_uint_t again; 392 ngx_uint_t again;
298 393
299 if (c->timedout) { 394 if (!c->ssl->shutdown_set) {
300 SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); 395
301 396 /* it seems that SSL_set_shutdown() could be called once only */
302 } else { 397
303 if (c->ssl->no_rcv_shut) { 398 if (c->read->timedout) {
304 SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); 399 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
305 } 400
306 401 } else {
307 if (c->ssl->no_send_shut) { 402 mode = 0;
308 SSL_set_shutdown(c->ssl->ssl, SSL_SENT_SHUTDOWN); 403
404 if (c->ssl->no_rcv_shut) {
405 mode = SSL_RECEIVED_SHUTDOWN;
406 }
407
408 if (c->ssl->no_send_shut) {
409 mode |= SSL_SENT_SHUTDOWN;
410 }
411 }
412
413 if (mode) {
414 SSL_set_shutdown(c->ssl->ssl, mode);
415 c->ssl->shutdown_set = 1;
309 } 416 }
310 } 417 }
311 418
312 again = 0; 419 again = 0;
313 #if (NGX_SUPPRESS_WARN) 420 #if (NGX_SUPPRESS_WARN)
317 for ( ;; ) { 424 for ( ;; ) {
318 n = SSL_shutdown(c->ssl->ssl); 425 n = SSL_shutdown(c->ssl->ssl);
319 426
320 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); 427 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
321 428
429 if (n == 1 || (n == 0 && c->read->timedout)) {
430 SSL_free(c->ssl->ssl);
431 c->ssl = NULL;
432 return NGX_OK;
433 }
434
322 if (n == 0) { 435 if (n == 0) {
323 again = 1; 436 again = 1;
324 break; 437 break;
325 } 438 }
326 439
327 if (n == 1) {
328 SSL_free(c->ssl->ssl);
329 c->ssl = NULL;
330 return NGX_OK;
331 }
332
333 break; 440 break;
334 } 441 }
335 442
336 if (!again) { 443 if (!again) {
337 sslerr = SSL_get_error(c->ssl->ssl, n); 444 sslerr = SSL_get_error(c->ssl->ssl, n);
340 "SSL_get_error: %d", sslerr); 447 "SSL_get_error: %d", sslerr);
341 } 448 }
342 449
343 if (again || sslerr == SSL_ERROR_WANT_READ) { 450 if (again || sslerr == SSL_ERROR_WANT_READ) {
344 451
345 ngx_add_timer(c->read, 10000); 452 ngx_add_timer(c->read, 30000);
346 453
347 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { 454 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
348 return NGX_ERROR; 455 return NGX_ERROR;
349 } 456 }
350 457