diff options
Diffstat (limited to 'src/event')
-rw-r--r-- | src/event/ngx_event_connect.c | 89 | ||||
-rw-r--r-- | src/event/ngx_event_openssl.c | 105 | ||||
-rw-r--r-- | src/event/ngx_event_openssl.h | 11 |
3 files changed, 176 insertions, 29 deletions
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index e4ca23840..157c48002 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -61,54 +61,75 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) /* it's a first try - get a current peer */ - pc->cur_peer = pc->peers->current; + for ( ;; ) { + pc->cur_peer = pc->peers->current; - pc->peers->weight--; + peer = &pc->peers->peer[pc->cur_peer]; + + if (peer->max_fails == 0 || peer->fails <= peer->max_fails) { + break; + } + + if (now - peer->accessed > peer->fail_timeout) { + peer->fails = 0; + break; + } - if (pc->peers->weight == 0) { pc->peers->current++; - } - if (pc->peers->current >= pc->peers->number) { - pc->peers->current = 0; - } + if (pc->peers->current >= pc->peers->number) { + pc->peers->current = 0; + } - if (pc->peers->weight == 0) { pc->peers->weight = pc->peers->peer[pc->peers->current].weight; - } - } - for ( ;; ) { - peer = &pc->peers->peer[pc->cur_peer]; + pc->tries--; - if (peer->max_fails == 0 || peer->fails <= peer->max_fails) { - break; - } + if (pc->tries) { + continue; + } - if (now - peer->accessed > peer->fail_timeout) { - peer->fails = 0; - break; + goto failed; } - pc->cur_peer++; + pc->peers->weight--; - if (pc->cur_peer >= pc->peers->number) { - pc->cur_peer = 0; + if (pc->peers->weight == 0) { + pc->peers->current++; + + if (pc->peers->current >= pc->peers->number) { + pc->peers->current = 0; + } + + pc->peers->weight = pc->peers->peer[pc->peers->current].weight; } - pc->tries--; + } else { + for ( ;; ) { + peer = &pc->peers->peer[pc->cur_peer]; - if (pc->tries == 0) { + if (peer->max_fails == 0 || peer->fails <= peer->max_fails) { + break; + } + + if (now - peer->accessed > peer->fail_timeout) { + peer->fails = 0; + break; + } - /* all peers failed, mark them as live for quick recovery */ + pc->cur_peer++; - for (i = 0; i < pc->peers->number; i++) { - pc->peers->peer[i].fails = 0; + if (pc->cur_peer >= pc->peers->number) { + pc->cur_peer = 0; } - /* ngx_unlock_mutex(pc->peers->mutex); */ + pc->tries--; + + if (pc->tries) { + continue; + } - return NGX_BUSY; + goto failed; } } } @@ -319,6 +340,18 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) wev->ready = 1; return NGX_OK; + +failed: + + /* all peers failed, mark them as live for quick recovery */ + + for (i = 0; i < pc->peers->number; i++) { + pc->peers->peer[i].fails = 0; + } + + /* ngx_unlock_mutex(pc->peers->mutex); */ + + return NGX_BUSY; } diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 3a7835ef6..0b217cffd 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -164,7 +164,8 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, } if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data, - SSL_FILETYPE_PEM) == 0) + SSL_FILETYPE_PEM) + == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data); @@ -176,6 +177,26 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t +ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert) +{ + if (ngx_conf_full_name(cf->cycle, cert) == NGX_ERROR) { + return NGX_ERROR; + } + + if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_load_verify_locations(\"%s\") failed", + cert->data); + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) { if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) { @@ -1023,6 +1044,88 @@ ngx_ssl_get_cipher_name(ngx_connection_t *c) } +ngx_int_t +ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + char *p; + size_t len; + X509 *cert; + X509_NAME *name; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert == NULL) { + return NGX_OK; + } + + name = X509_get_subject_name(cert); + + if (name == NULL) { + return NGX_ERROR; + } + + p = X509_NAME_oneline(name, NULL, 0); + + for (len = 0; p[len]; len++) { /* void */ } + + s->len = len; + s->data = ngx_palloc(pool, len); + if (s->data == NULL) { + OPENSSL_free(p); + return NGX_ERROR; + } + + ngx_memcpy(s->data, p, len); + + OPENSSL_free(p); + + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + char *p; + size_t len; + X509 *cert; + X509_NAME *name; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert == NULL) { + return NGX_OK; + } + + name = X509_get_issuer_name(cert); + + if (name == NULL) { + return NGX_ERROR; + } + + p = X509_NAME_oneline(name, NULL, 0); + + for (len = 0; p[len]; len++) { /* void */ } + + s->len = len; + s->data = ngx_palloc(pool, len); + if (s->data == NULL) { + OPENSSL_free(p); + return NGX_ERROR; + } + + ngx_memcpy(s->data, p, len); + + OPENSSL_free(p); + + return NGX_OK; +} + + static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 82bfa139f..4af42190b 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -31,6 +31,7 @@ typedef struct { typedef struct { SSL *connection; + ngx_int_t last; ngx_buf_t *buf; @@ -60,10 +61,15 @@ typedef struct { #define NGX_SSL_BUFSIZE 16384 +#define NGX_SSL_VERIFY SSL_VERIFY_PEER + + ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key); +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *cert); ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl); ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags); @@ -75,6 +81,11 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session); u_char *ngx_ssl_get_protocol(ngx_connection_t *c); u_char *ngx_ssl_get_cipher_name(ngx_connection_t *c); +ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); +ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); + ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); |