Only call ws_client_free once all scheduled events have triggered

Fixes #209. A WS client socket closure could cause Webdis to schedule
the send of a closing frame, leading to both EV_READ and EV_WRITE
scheduled events. They would both fail and each lead to a call to
ws_client_free, causing a double free that ends in a crash.
master
Jessie Murray 3 years ago
parent 55128ae263
commit 887e0ec73f
No known key found for this signature in database
GPG Key ID: E7E4D57EDDA744C5

@ -579,10 +579,8 @@ ws_can_read(int fd, short event, void *p) {
ws->scheduled_read = 0;
ret = evbuffer_read(ws->rbuf, fd, 4096);
if(ret <= 0) {
ws_client_free(ws); /* will close the socket */
} else if(ws->close_after_events) {
ws_close_if_able(ws);
if(ret <= 0 || ws->close_after_events) {
ws_close_if_able(ws); /* will close the socket once all events have triggered */
} else {
enum ws_state state = ws_process_read_data(ws, NULL);
if(state == WS_READING) { /* need more data, schedule new read */
@ -607,7 +605,7 @@ ws_can_write(int fd, short event, void *p) {
ret = evbuffer_write_atmost(ws->wbuf, fd, 4096);
if(ret <= 0) {
ws_client_free(ws); /* will close the socket */
ws_close_if_able(ws); /* will close the socket once all events have triggered */
} else {
if(evbuffer_get_length(ws->wbuf) > 0) { /* more data to send */
ws_schedule_write(ws);

Loading…
Cancel
Save