mirror of
https://github.com/nginx/nginx.git
synced 2025-01-05 13:44:56 -06:00
fix segfault when session was freed twice
This commit is contained in:
parent
f53d0f3177
commit
8b0a3d2810
@ -13,50 +13,56 @@
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
#define NGX_PEER_KEEPALIVE 1
|
||||
#define NGX_PEER_NEXT 2
|
||||
#define NGX_PEER_FAILED 4
|
||||
#define NGX_PEER_KEEPALIVE 1
|
||||
#define NGX_PEER_NEXT 2
|
||||
#define NGX_PEER_FAILED 4
|
||||
|
||||
|
||||
typedef struct ngx_peer_connection_s ngx_peer_connection_t;
|
||||
|
||||
typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
#if (NGX_SSL)
|
||||
typedef void (*ngx_event_save_peer_pt)(ngx_peer_connection_t *pc, void *data);
|
||||
#endif
|
||||
typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,
|
||||
ngx_uint_t state);
|
||||
#if (NGX_SSL)
|
||||
|
||||
typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
|
||||
struct ngx_peer_connection_s {
|
||||
ngx_connection_t *connection;
|
||||
ngx_connection_t *connection;
|
||||
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
ngx_str_t *name;
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
ngx_str_t *name;
|
||||
|
||||
ngx_uint_t tries;
|
||||
ngx_uint_t tries;
|
||||
|
||||
ngx_event_get_peer_pt get;
|
||||
ngx_event_free_peer_pt free;
|
||||
void *data;
|
||||
ngx_event_get_peer_pt get;
|
||||
ngx_event_free_peer_pt free;
|
||||
void *data;
|
||||
|
||||
#if (NGX_SSL)
|
||||
ngx_ssl_session_t *ssl_session;
|
||||
ngx_event_save_peer_pt save_session;
|
||||
ngx_event_set_peer_session_pt set_session;
|
||||
ngx_event_save_peer_session_pt save_session;
|
||||
#endif
|
||||
|
||||
#if (NGX_THREADS)
|
||||
ngx_atomic_t *lock;
|
||||
ngx_atomic_t *lock;
|
||||
#endif
|
||||
|
||||
int rcvbuf;
|
||||
int rcvbuf;
|
||||
|
||||
ngx_log_t *log;
|
||||
ngx_log_t *log;
|
||||
|
||||
unsigned cached:1;
|
||||
unsigned log_error:2; /* ngx_connection_log_error_e */
|
||||
unsigned cached:1;
|
||||
|
||||
/* ngx_connection_log_error_e */
|
||||
unsigned log_error:2;
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,9 +198,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
||||
pc->sockaddr = peer->sockaddr;
|
||||
pc->socklen = peer->socklen;
|
||||
pc->name = &peer->name;
|
||||
#if (NGX_SSL)
|
||||
pc->ssl_session = peer->ssl_session;
|
||||
#endif
|
||||
|
||||
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
|
||||
|
||||
|
@ -657,7 +657,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||
c->sendfile = 0;
|
||||
u->output.sendfile = 0;
|
||||
|
||||
if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) {
|
||||
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
@ -152,7 +152,10 @@ ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
|
||||
r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
|
||||
r->upstream->peer.tries = rrp->peers->number;
|
||||
#if (NGX_HTTP_SSL)
|
||||
r->upstream->peer.save_session = ngx_http_upstream_save_round_robin_peer;
|
||||
r->upstream->peer.set_session =
|
||||
ngx_http_upstream_set_round_robin_peer_session;
|
||||
r->upstream->peer.save_session =
|
||||
ngx_http_upstream_save_round_robin_peer_session;
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
@ -328,9 +331,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
|
||||
pc->sockaddr = peer->sockaddr;
|
||||
pc->socklen = peer->socklen;
|
||||
pc->name = &peer->name;
|
||||
#if (NGX_SSL)
|
||||
pc->ssl_session = peer->ssl_session;
|
||||
#endif
|
||||
|
||||
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||
|
||||
@ -408,29 +408,72 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
|
||||
void
|
||||
ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc, void *data)
|
||||
ngx_int_t
|
||||
ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
|
||||
void *data)
|
||||
{
|
||||
ngx_http_upstream_rr_peer_data_t *rrp = data;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_ssl_session_t *ssl_session;
|
||||
ngx_http_upstream_rr_peer_t *peer;
|
||||
|
||||
peer = &rrp->peers->peer[rrp->current];
|
||||
|
||||
/* TODO: threads only mutex */
|
||||
/* ngx_lock_mutex(rrp->peers->mutex); */
|
||||
|
||||
ssl_session = peer->ssl_session;
|
||||
|
||||
rc = ngx_ssl_set_session(pc->connection, ssl_session);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"set session: %p:%d",
|
||||
ssl_session, ssl_session ? ssl_session->references : 0);
|
||||
|
||||
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
|
||||
void *data)
|
||||
{
|
||||
ngx_http_upstream_rr_peer_data_t *rrp = data;
|
||||
|
||||
ngx_ssl_session_t *old_ssl_session, *ssl_session;
|
||||
ngx_http_upstream_rr_peer_t *peer;
|
||||
|
||||
ssl_session = ngx_ssl_get_session(pc->connection);
|
||||
|
||||
if (ssl_session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"save session: %p:%d", ssl_session, ssl_session->references);
|
||||
|
||||
peer = &rrp->peers->peer[rrp->current];
|
||||
|
||||
/* TODO: threads only mutex */
|
||||
/* ngx_lock_mutex(rrp->peers->mutex); */
|
||||
|
||||
old_ssl_session = peer->ssl_session;
|
||||
peer->ssl_session = ssl_session;
|
||||
|
||||
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||
|
||||
if (pc->ssl_session) {
|
||||
if (old_ssl_session) {
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||
"old session: %p:%d",
|
||||
old_ssl_session, old_ssl_session->references);
|
||||
|
||||
/* TODO: may block */
|
||||
ngx_ssl_free_session(pc->ssl_session);
|
||||
|
||||
ngx_ssl_free_session(old_ssl_session);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
ngx_uint_t down; /* unsigned down:1; */
|
||||
|
||||
#if (NGX_SSL)
|
||||
ngx_ssl_session_t *ssl_session;
|
||||
ngx_ssl_session_t *ssl_session; /* local to a process */
|
||||
#endif
|
||||
} ngx_http_upstream_rr_peer_t;
|
||||
|
||||
@ -68,7 +68,10 @@ void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
|
||||
void *data, ngx_uint_t state);
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
void ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc,
|
||||
ngx_int_t
|
||||
ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
void ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user