aboutsummaryrefslogtreecommitdiff
path: root/src/event
diff options
context:
space:
mode:
Diffstat (limited to 'src/event')
-rw-r--r--src/event/ngx_event_connect.c89
-rw-r--r--src/event/ngx_event_openssl.c105
-rw-r--r--src/event/ngx_event_openssl.h11
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);