Klaus Demo nginx / a901bd6
Merge of r5004, r5019-r5025: ssl fixes. *) SSL: speedup loading of configs with many ssl servers. The patch saves one EC_KEY_generate_key() call per server{} block by informing OpenSSL about SSL_OP_SINGLE_ECDH_USE we are going to use before the SSL_CTX_set_tmp_ecdh() call. For a configuration file with 10k simple server{} blocks with SSL enabled this change reduces startup time from 18s to 5s on a slow test box here. *) SSL: removed conditions that always hold true. *) SSL: resetting of flush flag after the data was written. There is no need to flush next chunk of data if it does not contain a buffer with the flush or last_buf flags set. *) SSL: preservation of flush flag for buffered data. Previously, if SSL buffer was not sent we lost information that the data must be flushed. *) SSL: calculation of buffer size moved closer to its usage. No functional changes. *) SSL: avoid calling SSL_write() with zero data size. According to documentation, calling SSL_write() with num=0 bytes to be sent results in undefined behavior. We don't currently call ngx_ssl_send_chain() with empty chain and buffer. This check handles the case of a chain with total data size that is a multiple of NGX_SSL_BUFSIZE, and with the special buffer at the end. In practice such cases resulted in premature connection close and critical error "SSL_write() failed (SSL:)" in the error log. *) SSL: take into account data in the buffer while limiting output. In some rare cases this can result in a more smooth sending rate. *) SSL: fixed ngx_ssl_handshake() with level-triggered event methods. Missing calls to ngx_handle_write_event() and ngx_handle_read_event() resulted in a CPU hog during SSL handshake if an level-triggered event method (e.g. select) was used. Maxim Dounin 6 years ago
1 changed file(s) with 27 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
527527 return NGX_ERROR;
528528 }
529529
530 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
531
530532 SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
531
532 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
533533
534534 EC_KEY_free(ecdh);
535535 #endif
692692 return NGX_ERROR;
693693 }
694694
695 if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
696 return NGX_ERROR;
697 }
698
695699 return NGX_AGAIN;
696700 }
697701
699703 c->write->ready = 0;
700704 c->read->handler = ngx_ssl_handshake_handler;
701705 c->write->handler = ngx_ssl_handshake_handler;
706
707 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
708 return NGX_ERROR;
709 }
702710
703711 if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
704712 return NGX_ERROR;
10521060 buf->end = buf->start + NGX_SSL_BUFSIZE;
10531061 }
10541062
1055 send = 0;
1056 flush = (in == NULL) ? 1 : 0;
1063 send = buf->last - buf->pos;
1064 flush = (in == NULL) ? 1 : buf->flush;
10571065
10581066 for ( ;; ) {
10591067
10751083
10761084 if (send + size > limit) {
10771085 size = (ssize_t) (limit - send);
1078 flush = 1;
10791086 }
10801087
10811088 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
10921099 }
10931100 }
10941101
1102 if (!flush && send < limit && buf->last < buf->end) {
1103 break;
1104 }
1105
10951106 size = buf->last - buf->pos;
10961107
1097 if (!flush && buf->last < buf->end && c->ssl->buffer) {
1098 break;
1108 if (size == 0) {
1109 buf->flush = 0;
1110 c->buffered &= ~NGX_SSL_BUFFERED;
1111 return in;
10991112 }
11001113
11011114 n = ngx_ssl_write(c, buf->pos, size);
11051118 }
11061119
11071120 if (n == NGX_AGAIN) {
1108 c->buffered |= NGX_SSL_BUFFERED;
1109 return in;
1121 break;
11101122 }
11111123
11121124 buf->pos += n;
11161128 break;
11171129 }
11181130
1119 if (buf->pos == buf->last) {
1120 buf->pos = buf->start;
1121 buf->last = buf->start;
1122 }
1131 flush = 0;
1132
1133 buf->pos = buf->start;
1134 buf->last = buf->start;
11231135
11241136 if (in == NULL || send == limit) {
11251137 break;
11261138 }
11271139 }
1140
1141 buf->flush = flush;
11281142
11291143 if (buf->pos < buf->last) {
11301144 c->buffered |= NGX_SSL_BUFFERED;