From 4e222f3f2772add6aa77a7c5535ab0c053c9318c Mon Sep 17 00:00:00 2001 From: Leonid Evdokimov Date: Thu, 17 Mar 2016 18:44:22 +0300 Subject: [PATCH] Avoid EBADF warnings from epoll using bufferevent_free more accurately --- http-connect.c | 3 +-- http-relay.c | 3 +-- redsocks.c | 20 ++++++++++++-------- redsocks.h | 3 +++ redudp.c | 11 +++-------- utils.c | 4 +++- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/http-connect.c b/http-connect.c index 685ab54..c0e5cf2 100644 --- a/http-connect.c +++ b/http-connect.c @@ -132,8 +132,7 @@ static void httpc_read_cb(struct bufferevent *buffev, void *_arg) } /* close relay tunnel */ - redsocks_close(EVENT_FD(&client->relay->ev_write)); - bufferevent_free(client->relay); + redsocks_bufferevent_free(client->relay); /* set to initial state*/ client->state = httpc_new; diff --git a/http-relay.c b/http-relay.c index 51c6f4c..24952d5 100644 --- a/http-relay.c +++ b/http-relay.c @@ -205,8 +205,7 @@ static void httpr_relay_read_cb(struct bufferevent *buffev, void *_arg) } /* close relay tunnel */ - redsocks_close(EVENT_FD(&client->relay->ev_write)); - bufferevent_free(client->relay); + redsocks_bufferevent_free(client->relay); /* set to initial state*/ client->state = httpr_recv_request_headers; diff --git a/redsocks.c b/redsocks.c index b65fb1a..50e102e 100644 --- a/redsocks.c +++ b/redsocks.c @@ -352,15 +352,11 @@ void redsocks_drop_client(redsocks_client *client) if (client->instance->relay_ss->fini) client->instance->relay_ss->fini(client); - if (client->client) { - redsocks_close(EVENT_FD(&client->client->ev_write)); - bufferevent_free(client->client); - } + if (client->client) + redsocks_bufferevent_free(client->client); - if (client->relay) { - redsocks_close(EVENT_FD(&client->relay->ev_write)); - bufferevent_free(client->relay); - } + if (client->relay) + redsocks_bufferevent_free(client->relay); list_del(&client->list); free(client); @@ -634,6 +630,14 @@ void redsocks_close_internal(int fd, const char* file, int line, const char *fun } } +void redsocks_bufferevent_free(struct bufferevent *buffev) +{ + int fd = bufferevent_getfd(buffev); + bufferevent_setfd(buffev, -1); // to avoid EBADFD warnings from epoll + bufferevent_free(buffev); + redsocks_close(fd); +} + static void redsocks_accept_client(int fd, short what, void *_arg) { redsocks_instance *self = _arg; diff --git a/redsocks.h b/redsocks.h index 4f072d5..2704e0c 100644 --- a/redsocks.h +++ b/redsocks.h @@ -94,6 +94,9 @@ int redsocks_write_helper( #define redsocks_close(fd) redsocks_close_internal((fd), __FILE__, __LINE__, __func__) void redsocks_close_internal(int fd, const char* file, int line, const char *func); +// I have to account descriptiors for accept-backoff, that's why BEV_OPT_CLOSE_ON_FREE is not used. +void redsocks_bufferevent_free(struct bufferevent *buffev); + #define redsocks_log_error(client, prio, msg...) \ redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, &(client)->destaddr, prio, ## msg) #define redsocks_log_errno(client, prio, msg...) \ diff --git a/redudp.c b/redudp.c index 05460dc..4c8d716 100644 --- a/redudp.c +++ b/redudp.c @@ -214,21 +214,16 @@ static struct evbuffer* socks5_mkassociate(void *p) */ static void redudp_drop_client(redudp_client *client) { - int fd; redudp_log_error(client, LOG_INFO, "Dropping..."); enqueued_packet *q, *tmp; if (event_initialized(&client->timeout)) { if (event_del(&client->timeout) == -1) redudp_log_errno(client, LOG_ERR, "event_del"); } - if (client->relay) { - fd = EVENT_FD(&client->relay->ev_read); - bufferevent_free(client->relay); - shutdown(fd, SHUT_RDWR); - redsocks_close(fd); - } + if (client->relay) + redsocks_bufferevent_free(client->relay); if (event_initialized(&client->udprelay)) { - fd = EVENT_FD(&client->udprelay); + int fd = EVENT_FD(&client->udprelay); if (event_del(&client->udprelay) == -1) redudp_log_errno(client, LOG_ERR, "event_del"); redsocks_close(fd); diff --git a/utils.c b/utils.c index 9c878e6..b101596 100644 --- a/utils.c +++ b/utils.c @@ -149,6 +149,8 @@ struct bufferevent* red_connect_relay(struct sockaddr_in *addr, evbuffercb write goto fail; } + relay_fd = -1; + error = bufferevent_enable(retval, EV_WRITE); // we wait for connection... if (error) { log_errno(LOG_ERR, "bufferevent_enable"); @@ -161,7 +163,7 @@ fail: if (relay_fd != -1) redsocks_close(relay_fd); if (retval) - bufferevent_free(retval); + redsocks_bufferevent_free(retval); return NULL; }