Skip to content

Commit 5953573

Browse files
committed
fix ssl shutdown management
1 parent 568348e commit 5953573

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

plugins/corerouter/corerouter.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
6565
free(peer->tmp_socket_name);
6666
peer->tmp_socket_name = NULL;
6767
}
68+
6869
cr_del_timeout(peer->session->corerouter, peer);
6970

7071
if (peer->fd != -1) {
@@ -84,7 +85,14 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
8485
}
8586

8687
// destroy a peer
87-
void uwsgi_cr_peer_del(struct corerouter_peer *peer) {
88+
int uwsgi_cr_peer_del(struct corerouter_peer *peer) {
89+
// first of all check if we need to run a flush procedure
90+
if (peer->flush && !peer->is_flushing) {
91+
peer->is_flushing = 1;
92+
// on success, suspend the execution
93+
if (peer->flush(peer) >= 0) return -1;
94+
}
95+
8896
struct corerouter_peer *prev = peer->prev;
8997
struct corerouter_peer *next = peer->next;
9098

@@ -115,6 +123,7 @@ void uwsgi_cr_peer_del(struct corerouter_peer *peer) {
115123
free(peer->key);
116124
}
117125
free(peer);
126+
return 0;
118127
}
119128

120129
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
397406
}
398407

399408
end:
400-
uwsgi_cr_peer_del(peer);
409+
if (uwsgi_cr_peer_del(peer) < 0) return;
401410

402411
if (peer == cs->main_peer) {
403412
cs->main_peer = NULL;
@@ -415,7 +424,7 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
415424

416425
struct corerouter_peer *main_peer = cr_session->main_peer;
417426
if (main_peer) {
418-
uwsgi_cr_peer_del(main_peer);
427+
if (uwsgi_cr_peer_del(main_peer) < 0) return;
419428
}
420429

421430
// free peers
@@ -427,7 +436,7 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
427436
if (ucr->subscriptions && tmp_peer->un && tmp_peer->un->len) {
428437
tmp_peer->un->reference--;
429438
}
430-
uwsgi_cr_peer_del(tmp_peer);
439+
if (uwsgi_cr_peer_del(tmp_peer) < 0) return;
431440
}
432441

433442
// could be used to free additional resources

plugins/corerouter/cr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ struct corerouter_peer {
195195
char proto;
196196

197197
int free_key;
198+
199+
ssize_t (*flush)(struct corerouter_peer *);
200+
int is_flushing;
198201
};
199202

200203
struct uwsgi_corerouter {

plugins/http/https.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,47 @@ ssize_t hr_ssl_read(struct corerouter_peer *main_peer) {
374374
return -1;
375375
}
376376

377+
ssize_t hr_ssl_shutdown(struct corerouter_peer *peer) {
378+
// ensure no hooks are set
379+
if (uwsgi_cr_set_hooks(peer, NULL, NULL)) return -1;
380+
381+
struct corerouter_session *cs = peer->session;
382+
struct http_session *hr = (struct http_session *) cs;
383+
384+
int ret = SSL_shutdown(hr->ssl);
385+
if (ret < 0) return -1;
386+
if (ret == 1) return 0;
387+
388+
int err = 0;
389+
390+
if (ERR_peek_error()) {
391+
err = SSL_get_error(hr->ssl, ret);
392+
}
393+
394+
// no error, close the connection
395+
if (err == 0 || err == SSL_ERROR_ZERO_RETURN) return -1;
396+
397+
if (err == SSL_ERROR_WANT_READ) {
398+
if (uwsgi_cr_set_hooks(peer, hr_ssl_shutdown, NULL)) return -1;
399+
return 1;
400+
}
401+
402+
else if (err == SSL_ERROR_WANT_WRITE) {
403+
if (uwsgi_cr_set_hooks(peer, NULL, hr_ssl_shutdown)) return -1;
404+
return 1;
405+
}
406+
407+
else if (err == SSL_ERROR_SYSCALL) {
408+
uwsgi_cr_error(peer, "hr_ssl_shutdown()");
409+
}
410+
411+
else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
412+
ERR_print_errors_fp(stderr);
413+
}
414+
415+
return -1;
416+
}
417+
377418
void hr_setup_ssl(struct http_session *hr, struct uwsgi_gateway_socket *ugs) {
378419
hr->ssl = SSL_new(ugs->ctx);
379420
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) {
382423
SSL_set_ex_data(hr->ssl, uhttp.spdy_index, hr);
383424
#endif
384425
uwsgi_cr_set_hooks(hr->session.main_peer, hr_ssl_read, NULL);
426+
hr->session.main_peer->flush = hr_ssl_shutdown;
385427
hr->session.close = hr_session_ssl_close;
386428
hr->func_write = hr_ssl_write;
387429
}

0 commit comments

Comments
 (0)