Mercurial > hg > nginx-quic
comparison src/event/ngx_event_openssl.c @ 473:8e8f3af115b5 release-0.1.11
nginx-0.1.11-RELEASE import
*) 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 <igor@sysoev.ru> |
---|---|
date | Thu, 02 Dec 2004 18:40:46 +0000 |
parents | 2ff194b74f1e |
children | c52408583801 |
comparison
equal
deleted
inserted
replaced
472:a004b617422d | 473:8e8f3af115b5 |
---|---|
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 |