fix ssl shutdown management

This commit is contained in:
Unbit
2014-10-24 11:43:18 +02:00
parent 568348e746
commit 5953573c3b
3 changed files with 58 additions and 4 deletions
+13 -4
View File
@@ -65,6 +65,7 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
free(peer->tmp_socket_name);
peer->tmp_socket_name = NULL;
}
cr_del_timeout(peer->session->corerouter, peer);
if (peer->fd != -1) {
@@ -84,7 +85,14 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
}
// destroy a peer
void uwsgi_cr_peer_del(struct corerouter_peer *peer) {
int uwsgi_cr_peer_del(struct corerouter_peer *peer) {
// first of all check if we need to run a flush procedure
if (peer->flush && !peer->is_flushing) {
peer->is_flushing = 1;
// on success, suspend the execution
if (peer->flush(peer) >= 0) return -1;
}
struct corerouter_peer *prev = peer->prev;
struct corerouter_peer *next = peer->next;
@@ -115,6 +123,7 @@ void uwsgi_cr_peer_del(struct corerouter_peer *peer) {
free(peer->key);
}
free(peer);
return 0;
}
void uwsgi_opt_corerouter(char *opt, char *value, void *cr) {
@@ -397,7 +406,7 @@ void corerouter_close_peer(struct uwsgi_corerouter *ucr, struct corerouter_peer
}
end:
uwsgi_cr_peer_del(peer);
if (uwsgi_cr_peer_del(peer) < 0) return;
if (peer == cs->main_peer) {
cs->main_peer = NULL;
@@ -415,7 +424,7 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
struct corerouter_peer *main_peer = cr_session->main_peer;
if (main_peer) {
uwsgi_cr_peer_del(main_peer);
if (uwsgi_cr_peer_del(main_peer) < 0) return;
}
// free peers
@@ -427,7 +436,7 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
if (ucr->subscriptions && tmp_peer->un && tmp_peer->un->len) {
tmp_peer->un->reference--;
}
uwsgi_cr_peer_del(tmp_peer);
if (uwsgi_cr_peer_del(tmp_peer) < 0) return;
}
// could be used to free additional resources
+3
View File
@@ -195,6 +195,9 @@ struct corerouter_peer {
char proto;
int free_key;
ssize_t (*flush)(struct corerouter_peer *);
int is_flushing;
};
struct uwsgi_corerouter {
+42
View File
@@ -374,6 +374,47 @@ ssize_t hr_ssl_read(struct corerouter_peer *main_peer) {
return -1;
}
ssize_t hr_ssl_shutdown(struct corerouter_peer *peer) {
// ensure no hooks are set
if (uwsgi_cr_set_hooks(peer, NULL, NULL)) return -1;
struct corerouter_session *cs = peer->session;
struct http_session *hr = (struct http_session *) cs;
int ret = SSL_shutdown(hr->ssl);
if (ret < 0) return -1;
if (ret == 1) return 0;
int err = 0;
if (ERR_peek_error()) {
err = SSL_get_error(hr->ssl, ret);
}
// no error, close the connection
if (err == 0 || err == SSL_ERROR_ZERO_RETURN) return -1;
if (err == SSL_ERROR_WANT_READ) {
if (uwsgi_cr_set_hooks(peer, hr_ssl_shutdown, NULL)) return -1;
return 1;
}
else if (err == SSL_ERROR_WANT_WRITE) {
if (uwsgi_cr_set_hooks(peer, NULL, hr_ssl_shutdown)) return -1;
return 1;
}
else if (err == SSL_ERROR_SYSCALL) {
uwsgi_cr_error(peer, "hr_ssl_shutdown()");
}
else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
ERR_print_errors_fp(stderr);
}
return -1;
}
void hr_setup_ssl(struct http_session *hr, struct uwsgi_gateway_socket *ugs) {
hr->ssl = SSL_new(ugs->ctx);
SSL_set_fd(hr->ssl, hr->session.main_peer->fd);
@@ -382,6 +423,7 @@ void hr_setup_ssl(struct http_session *hr, struct uwsgi_gateway_socket *ugs) {
SSL_set_ex_data(hr->ssl, uhttp.spdy_index, hr);
#endif
uwsgi_cr_set_hooks(hr->session.main_peer, hr_ssl_read, NULL);
hr->session.main_peer->flush = hr_ssl_shutdown;
hr->session.close = hr_session_ssl_close;
hr->func_write = hr_ssl_write;
}