Mercurial > hg > nginx-vendor-0-8
comparison src/event/ngx_event_openssl.c @ 126:df17fbafec8f NGINX_0_3_10
nginx 0.3.10
*) Change: the "valid_referers" directive and the "$invalid_referer"
variable were moved to the new ngx_http_referer_module from the
ngx_http_rewrite_module.
*) Change: the "$apache_bytes_sent" variable name was changed to
"$body_bytes_sent".
*) Feature: the "$sent_http_..." variables.
*) Feature: the "if" directive supports the "=" and "!=" operations.
*) Feature: the "proxy_pass" directive supports the HTTPS protocol.
*) Feature: the "proxy_set_body" directive.
*) Feature: the "post_action" directive.
*) Feature: the ngx_http_empty_gif_module.
*) Feature: the "worker_cpu_affinity" directive for Linux.
*) Bugfix: the "rewrite" directive did not unescape URI part in
redirect, now it is unescaped except the %00-%25 and %7F-%FF
characters.
*) Bugfix: nginx could not be built by the icc 9.0 compiler.
*) Bugfix: if the SSI was enabled for zero size static file, then the
chunked response was encoded incorrectly.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 15 Nov 2005 00:00:00 +0300 |
parents | e85dca77c46a |
children | 91372f004adf |
comparison
equal
deleted
inserted
replaced
125:97504de1f89e | 126:df17fbafec8f |
---|---|
16 | 16 |
17 static void ngx_ssl_handshake_handler(ngx_event_t *ev); | 17 static void ngx_ssl_handshake_handler(ngx_event_t *ev); |
18 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); | 18 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); |
19 static void ngx_ssl_write_handler(ngx_event_t *wev); | 19 static void ngx_ssl_write_handler(ngx_event_t *wev); |
20 static void ngx_ssl_read_handler(ngx_event_t *rev); | 20 static void ngx_ssl_read_handler(ngx_event_t *rev); |
21 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); | |
21 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, | 22 static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, |
22 ngx_err_t err, char *text); | 23 ngx_err_t err, char *text); |
23 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); | 24 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); |
24 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); | 25 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); |
25 static void ngx_openssl_exit(ngx_cycle_t *cycle); | 26 static void ngx_openssl_exit(ngx_cycle_t *cycle); |
49 | 50 |
50 static ngx_core_module_t ngx_openssl_module_ctx = { | 51 static ngx_core_module_t ngx_openssl_module_ctx = { |
51 ngx_string("openssl"), | 52 ngx_string("openssl"), |
52 ngx_openssl_create_conf, | 53 ngx_openssl_create_conf, |
53 ngx_openssl_init_conf | 54 ngx_openssl_init_conf |
54 }; | 55 }; |
55 | 56 |
56 | 57 |
57 ngx_module_t ngx_openssl_module = { | 58 ngx_module_t ngx_openssl_module = { |
58 NGX_MODULE_V1, | 59 NGX_MODULE_V1, |
59 &ngx_openssl_module_ctx, /* module context */ | 60 &ngx_openssl_module_ctx, /* module context */ |
97 | 98 |
98 | 99 |
99 ngx_int_t | 100 ngx_int_t |
100 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols) | 101 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols) |
101 { | 102 { |
102 ssl->ctx = SSL_CTX_new(SSLv23_server_method()); | 103 ssl->ctx = SSL_CTX_new(SSLv23_method()); |
103 | 104 |
104 if (ssl->ctx == NULL) { | 105 if (ssl->ctx == NULL) { |
105 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); | 106 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); |
106 return NGX_ERROR; | 107 return NGX_ERROR; |
107 } | 108 } |
108 | 109 |
109 /* | 110 /* client side options */ |
110 * these options are needed on client side only: | 111 |
111 * SSL_OP_MICROSOFT_SESS_ID_BUG | 112 SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG); |
112 * SSL_OP_NETSCAPE_CHALLENGE_BUG | 113 SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG); |
113 * SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG | 114 SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); |
114 */ | 115 |
116 /* server side options */ | |
115 | 117 |
116 SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); | 118 SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); |
117 SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); | 119 SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); |
118 | 120 |
119 /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */ | 121 /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */ |
193 } | 195 } |
194 | 196 |
195 | 197 |
196 ngx_int_t | 198 ngx_int_t |
197 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags) | 199 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags) |
198 { | 200 { |
199 ngx_ssl_connection_t *sc; | 201 ngx_ssl_connection_t *sc; |
200 | 202 |
201 sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); | 203 sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); |
202 if (sc == NULL) { | 204 if (sc == NULL) { |
203 return NGX_ERROR; | 205 return NGX_ERROR; |
222 if (SSL_set_fd(sc->connection, c->fd) == 0) { | 224 if (SSL_set_fd(sc->connection, c->fd) == 0) { |
223 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); | 225 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); |
224 return NGX_ERROR; | 226 return NGX_ERROR; |
225 } | 227 } |
226 | 228 |
227 SSL_set_accept_state(sc->connection); | 229 if (flags & NGX_SSL_CLIENT) { |
230 SSL_set_connect_state(sc->connection); | |
231 | |
232 } else { | |
233 SSL_set_accept_state(sc->connection); | |
234 } | |
228 | 235 |
229 c->ssl = sc; | 236 c->ssl = sc; |
237 | |
238 return NGX_OK; | |
239 } | |
240 | |
241 | |
242 ngx_int_t | |
243 ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session) | |
244 { | |
245 if (session) { | |
246 if (SSL_set_session(c->ssl->connection, session) == 0) { | |
247 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed"); | |
248 return NGX_ERROR; | |
249 } | |
250 } | |
230 | 251 |
231 return NGX_OK; | 252 return NGX_OK; |
232 } | 253 } |
233 | 254 |
234 | 255 |
238 int n, sslerr; | 259 int n, sslerr; |
239 ngx_err_t err; | 260 ngx_err_t err; |
240 | 261 |
241 n = SSL_do_handshake(c->ssl->connection); | 262 n = SSL_do_handshake(c->ssl->connection); |
242 | 263 |
243 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | 264 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
244 | 265 |
245 if (n == 1) { | 266 if (n == 1) { |
246 | 267 |
247 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | 268 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
248 return NGX_ERROR; | 269 return NGX_ERROR; |
280 | 301 |
281 *d = '\0'; | 302 *d = '\0'; |
282 | 303 |
283 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 304 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
284 "SSL: %s, cipher: \"%s\"", | 305 "SSL: %s, cipher: \"%s\"", |
285 SSL_get_version(c->ssl->connection), &buf[1]); | 306 SSL_get_version(c->ssl->connection), &buf[1]); |
286 | 307 |
287 if (SSL_session_reused(c->ssl->connection)) { | 308 if (SSL_session_reused(c->ssl->connection)) { |
288 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 309 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
289 "SSL reused session"); | 310 "SSL reused session"); |
290 } | 311 } |
291 | 312 |
292 } else { | 313 } else { |
293 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | 314 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
294 "SSL no shared ciphers"); | 315 "SSL no shared ciphers"); |
295 } | 316 } |
296 } | 317 } |
297 #endif | 318 #endif |
298 | 319 |
299 c->ssl->handshaked = 1; | 320 c->ssl->handshaked = 1; |
300 | 321 |
301 c->recv = ngx_ssl_recv; | 322 c->recv = ngx_ssl_recv; |
302 c->send = ngx_ssl_write; | 323 c->send = ngx_ssl_write; |
303 c->send_chain = ngx_ssl_send_chain; | 324 c->recv_chain = ngx_ssl_recv_chain; |
325 c->send_chain = ngx_ssl_send_chain; | |
304 | 326 |
305 return NGX_OK; | 327 return NGX_OK; |
306 } | 328 } |
307 | 329 |
308 sslerr = SSL_get_error(c->ssl->connection, n); | 330 sslerr = SSL_get_error(c->ssl->connection, n); |
336 c->ssl->no_wait_shutdown = 1; | 358 c->ssl->no_wait_shutdown = 1; |
337 c->ssl->no_send_shutdown = 1; | 359 c->ssl->no_send_shutdown = 1; |
338 | 360 |
339 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { | 361 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { |
340 ngx_log_error(NGX_LOG_INFO, c->log, err, | 362 ngx_log_error(NGX_LOG_INFO, c->log, err, |
341 "client closed connection in SSL handshake"); | 363 "peer closed connection in SSL handshake"); |
342 | 364 |
343 return NGX_ERROR; | 365 return NGX_ERROR; |
344 } | 366 } |
345 | 367 |
346 ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed"); | 368 ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed"); |
355 ngx_connection_t *c; | 377 ngx_connection_t *c; |
356 | 378 |
357 c = ev->data; | 379 c = ev->data; |
358 | 380 |
359 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 381 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
360 "ssl handshake handler: %d", ev->write); | 382 "SSL handshake handler: %d", ev->write); |
361 | 383 |
362 if (ngx_ssl_handshake(c) == NGX_AGAIN) { | 384 if (ngx_ssl_handshake(c) == NGX_AGAIN) { |
363 return; | 385 return; |
364 } | 386 } |
365 | 387 |
366 c->ssl->handler(c); | 388 c->ssl->handler(c); |
367 } | 389 } |
368 | 390 |
369 | 391 |
370 ssize_t | 392 ssize_t |
393 ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl) | |
394 { | |
395 ssize_t n, bytes; | |
396 ngx_buf_t *b; | |
397 | |
398 bytes = 0; | |
399 | |
400 while (cl) { | |
401 b = cl->buf; | |
402 | |
403 n = ngx_ssl_recv(c, b->last, b->end - b->last); | |
404 | |
405 if (n > 0) { | |
406 b->last += n; | |
407 bytes += n; | |
408 | |
409 if (b->last == b->end) { | |
410 cl = cl->next; | |
411 } | |
412 | |
413 continue; | |
414 } | |
415 | |
416 if (bytes) { | |
417 return bytes; | |
418 } | |
419 | |
420 return n; | |
421 } | |
422 | |
423 return bytes; | |
424 } | |
425 | |
426 | |
427 ssize_t | |
371 ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) | 428 ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) |
372 { | 429 { |
373 int n, bytes; | 430 int n, bytes; |
374 | 431 |
375 if (c->ssl->last == NGX_ERROR) { | 432 if (c->ssl->last == NGX_ERROR) { |
376 return NGX_ERROR; | 433 return NGX_ERROR; |
434 } | |
435 | |
436 if (c->ssl->last == NGX_DONE) { | |
437 return 0; | |
377 } | 438 } |
378 | 439 |
379 bytes = 0; | 440 bytes = 0; |
380 | 441 |
381 /* | 442 /* |
385 | 446 |
386 for ( ;; ) { | 447 for ( ;; ) { |
387 | 448 |
388 n = SSL_read(c->ssl->connection, buf, size); | 449 n = SSL_read(c->ssl->connection, buf, size); |
389 | 450 |
390 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); | 451 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); |
391 | 452 |
392 if (n > 0) { | 453 if (n > 0) { |
393 bytes += n; | 454 bytes += n; |
394 } | 455 } |
395 | 456 |
397 | 458 |
398 if (c->ssl->last != NGX_OK) { | 459 if (c->ssl->last != NGX_OK) { |
399 | 460 |
400 if (bytes) { | 461 if (bytes) { |
401 return bytes; | 462 return bytes; |
402 | 463 } |
403 } else { | 464 |
404 return c->ssl->last; | 465 if (c->ssl->last == NGX_DONE) { |
405 } | 466 return 0; |
467 } | |
468 | |
469 return c->ssl->last; | |
406 } | 470 } |
407 | 471 |
408 size -= n; | 472 size -= n; |
409 | 473 |
410 if (size == 0) { | 474 if (size == 0) { |
452 } | 516 } |
453 | 517 |
454 if (sslerr == SSL_ERROR_WANT_WRITE) { | 518 if (sslerr == SSL_ERROR_WANT_WRITE) { |
455 | 519 |
456 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 520 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
457 "client started SSL renegotiation"); | 521 "peer started SSL renegotiation"); |
458 | 522 |
459 c->write->ready = 0; | 523 c->write->ready = 0; |
460 | 524 |
461 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | 525 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
462 return NGX_ERROR; | 526 return NGX_ERROR; |
476 | 540 |
477 c->ssl->no_wait_shutdown = 1; | 541 c->ssl->no_wait_shutdown = 1; |
478 c->ssl->no_send_shutdown = 1; | 542 c->ssl->no_send_shutdown = 1; |
479 | 543 |
480 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { | 544 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { |
481 ngx_log_error(NGX_LOG_INFO, c->log, err, "client closed connection"); | 545 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
482 | 546 "peer shutdown SSL cleanly"); |
483 return NGX_ERROR; | 547 return NGX_DONE; |
484 } | 548 } |
485 | 549 |
486 ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed"); | 550 ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed"); |
487 | 551 |
488 return NGX_ERROR; | 552 return NGX_ERROR; |
514 int n; | 578 int n; |
515 ngx_uint_t flush; | 579 ngx_uint_t flush; |
516 ssize_t send, size; | 580 ssize_t send, size; |
517 ngx_buf_t *buf; | 581 ngx_buf_t *buf; |
518 | 582 |
519 buf = c->ssl->buf; | 583 if (!c->ssl->buffer || (in && in->next == NULL && !c->buffered)) { |
520 | |
521 if (in && in->next == NULL && !c->buffered && !c->ssl->buffer) { | |
522 | 584 |
523 /* | 585 /* |
524 * we avoid a buffer copy if the incoming buf is a single, | 586 * we avoid a buffer copy if |
525 * our buffer is empty, and we do not need to buffer the output | 587 * we do not need to buffer the output |
588 * or the incoming buf is a single and our buffer is empty | |
526 */ | 589 */ |
527 | 590 |
528 n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos); | 591 while (in) { |
529 | 592 if (ngx_buf_special(in->buf)) { |
530 if (n == NGX_ERROR) { | 593 in = in->next; |
531 return NGX_CHAIN_ERROR; | 594 continue; |
532 } | 595 } |
533 | 596 |
534 if (n == NGX_AGAIN) { | 597 n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos); |
535 c->buffered = 1; | 598 |
536 return in; | 599 if (n == NGX_ERROR) { |
537 } | 600 return NGX_CHAIN_ERROR; |
538 | 601 } |
539 in->buf->pos += n; | 602 |
603 if (n == NGX_AGAIN) { | |
604 c->buffered = 1; | |
605 return in; | |
606 } | |
607 | |
608 in->buf->pos += n; | |
609 | |
610 if (in->buf->pos == in->buf->last) { | |
611 in = in->next; | |
612 } | |
613 } | |
540 | 614 |
541 return in; | 615 return in; |
542 } | 616 } |
543 | 617 |
544 | 618 |
547 if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) { | 621 if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) { |
548 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize; | 622 limit = NGX_MAX_UINT32_VALUE - ngx_pagesize; |
549 } | 623 } |
550 | 624 |
551 | 625 |
626 buf = c->ssl->buf; | |
552 send = 0; | 627 send = 0; |
553 flush = (in == NULL) ? 1 : 0; | 628 flush = (in == NULL) ? 1 : 0; |
554 | 629 |
555 for ( ;; ) { | 630 for ( ;; ) { |
556 | 631 |
574 * TODO: the taking in->buf->flush into account can be | 649 * TODO: the taking in->buf->flush into account can be |
575 * implemented using the limit on the higher level | 650 * implemented using the limit on the higher level |
576 */ | 651 */ |
577 | 652 |
578 if (send + size > limit) { | 653 if (send + size > limit) { |
579 size = limit - send; | 654 size = (ssize_t) (limit - send); |
580 flush = 1; | 655 flush = 1; |
581 } | 656 } |
582 | 657 |
583 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 658 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
584 "SSL buf copy: %d", size); | 659 "SSL buf copy: %d", size); |
586 ngx_memcpy(buf->last, in->buf->pos, size); | 661 ngx_memcpy(buf->last, in->buf->pos, size); |
587 | 662 |
588 buf->last += size; | 663 buf->last += size; |
589 | 664 |
590 in->buf->pos += size; | 665 in->buf->pos += size; |
666 | |
591 if (in->buf->pos == in->buf->last) { | 667 if (in->buf->pos == in->buf->last) { |
592 in = in->next; | 668 in = in->next; |
593 } | 669 } |
594 } | 670 } |
595 | 671 |
676 } | 752 } |
677 | 753 |
678 if (sslerr == SSL_ERROR_WANT_READ) { | 754 if (sslerr == SSL_ERROR_WANT_READ) { |
679 | 755 |
680 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 756 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
681 "client started SSL renegotiation"); | 757 "peer started SSL renegotiation"); |
682 | 758 |
683 c->read->ready = 0; | 759 c->read->ready = 0; |
684 | 760 |
685 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | 761 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
686 return NGX_ERROR; | 762 return NGX_ERROR; |
723 ngx_ssl_shutdown(ngx_connection_t *c) | 799 ngx_ssl_shutdown(ngx_connection_t *c) |
724 { | 800 { |
725 int n, sslerr, mode; | 801 int n, sslerr, mode; |
726 ngx_uint_t again; | 802 ngx_uint_t again; |
727 | 803 |
728 if (c->read->timedout) { | 804 if (c->timedout) { |
729 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; | 805 mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; |
730 | 806 |
731 } else { | 807 } else { |
732 mode = SSL_get_shutdown(c->ssl->connection); | 808 mode = SSL_get_shutdown(c->ssl->connection); |
733 | 809 |
750 for ( ;; ) { | 826 for ( ;; ) { |
751 n = SSL_shutdown(c->ssl->connection); | 827 n = SSL_shutdown(c->ssl->connection); |
752 | 828 |
753 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); | 829 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); |
754 | 830 |
755 if (n == 1 || (n == 0 && c->read->timedout)) { | 831 if (n == 1 || (n == 0 && c->timedout)) { |
756 SSL_free(c->ssl->connection); | 832 SSL_free(c->ssl->connection); |
757 c->ssl = NULL; | 833 c->ssl = NULL; |
758 | 834 |
759 return NGX_OK; | 835 return NGX_OK; |
760 } | 836 } |
776 | 852 |
777 if (again || sslerr == SSL_ERROR_WANT_READ) { | 853 if (again || sslerr == SSL_ERROR_WANT_READ) { |
778 | 854 |
779 ngx_add_timer(c->read, 30000); | 855 ngx_add_timer(c->read, 30000); |
780 | 856 |
857 c->read->handler = ngx_ssl_shutdown_handler; | |
858 | |
781 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | 859 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
782 return NGX_ERROR; | 860 return NGX_ERROR; |
783 } | 861 } |
784 | 862 |
785 return NGX_AGAIN; | 863 return NGX_AGAIN; |
786 } | 864 } |
787 | 865 |
788 if (sslerr == SSL_ERROR_WANT_WRITE) { | 866 if (sslerr == SSL_ERROR_WANT_WRITE) { |
789 | 867 |
868 c->write->handler = ngx_ssl_shutdown_handler; | |
869 | |
790 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | 870 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
791 return NGX_ERROR; | 871 return NGX_ERROR; |
792 } | 872 } |
793 | 873 |
794 return NGX_AGAIN; | 874 return NGX_AGAIN; |
798 | 878 |
799 SSL_free(c->ssl->connection); | 879 SSL_free(c->ssl->connection); |
800 c->ssl = NULL; | 880 c->ssl = NULL; |
801 | 881 |
802 return NGX_ERROR; | 882 return NGX_ERROR; |
883 } | |
884 | |
885 | |
886 static void | |
887 ngx_ssl_shutdown_handler(ngx_event_t *ev) | |
888 { | |
889 ngx_connection_t *c; | |
890 ngx_connection_handler_pt handler; | |
891 | |
892 c = ev->data; | |
893 handler = c->ssl->handler; | |
894 | |
895 if (ev->timedout) { | |
896 c->timedout = 1; | |
897 } | |
898 | |
899 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "SSL shutdown handler"); | |
900 | |
901 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
902 return; | |
903 } | |
904 | |
905 handler(c); | |
803 } | 906 } |
804 | 907 |
805 | 908 |
806 static void | 909 static void |
807 ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, | 910 ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, |
840 } | 943 } |
841 | 944 |
842 | 945 |
843 void | 946 void |
844 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) | 947 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) |
845 { | 948 { |
846 u_long n; | 949 u_long n; |
847 va_list args; | 950 va_list args; |
848 u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last; | 951 u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last; |
849 | 952 |
850 last = errstr + NGX_MAX_CONF_ERRSTR; | 953 last = errstr + NGX_MAX_CONF_ERRSTR; |
885 | 988 |
886 static void * | 989 static void * |
887 ngx_openssl_create_conf(ngx_cycle_t *cycle) | 990 ngx_openssl_create_conf(ngx_cycle_t *cycle) |
888 { | 991 { |
889 ngx_openssl_conf_t *oscf; | 992 ngx_openssl_conf_t *oscf; |
890 | 993 |
891 oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t)); | 994 oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t)); |
892 if (oscf == NULL) { | 995 if (oscf == NULL) { |
893 return NGX_CONF_ERROR; | 996 return NGX_CONF_ERROR; |
894 } | 997 } |
895 | 998 |
896 /* | 999 /* |
897 * set by ngx_pcalloc(): | 1000 * set by ngx_pcalloc(): |
898 * | 1001 * |
899 * oscf->engine.len = 0; | 1002 * oscf->engine.len = 0; |
900 * oscf->engine.data = NULL; | 1003 * oscf->engine.data = NULL; |
901 */ | 1004 */ |
902 | 1005 |
903 return oscf; | 1006 return oscf; |
904 } | 1007 } |
905 | 1008 |
906 | 1009 |
913 ENGINE *engine; | 1016 ENGINE *engine; |
914 | 1017 |
915 if (oscf->engine.len == 0) { | 1018 if (oscf->engine.len == 0) { |
916 return NGX_CONF_OK; | 1019 return NGX_CONF_OK; |
917 } | 1020 } |
918 | 1021 |
919 engine = ENGINE_by_id((const char *) oscf->engine.data); | 1022 engine = ENGINE_by_id((const char *) oscf->engine.data); |
920 | 1023 |
921 if (engine == NULL) { | 1024 if (engine == NULL) { |
922 ngx_ssl_error(NGX_LOG_WARN, cycle->log, 0, | 1025 ngx_ssl_error(NGX_LOG_WARN, cycle->log, 0, |
923 "ENGINE_by_id(\"%V\") failed", &oscf->engine); | 1026 "ENGINE_by_id(\"%V\") failed", &oscf->engine); |