Skip to content

Commit

Permalink
Merge branch 'evconnlistener-do-not-close-client-fd'
Browse files Browse the repository at this point in the history
Fixes: #577

* evconnlistener-do-not-close-client-fd:
  listener: cover closing of fd in case evconnlistener_free() called from acceptcb
  Revert "Fix potential fd leak in listener_read_cb()"
  • Loading branch information
azat committed Dec 10, 2017
2 parents 6ee73ea + 8a460e3 commit bc65ffc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
2 changes: 0 additions & 2 deletions listener.c
Expand Up @@ -421,8 +421,6 @@ listener_read_cb(evutil_socket_t fd, short what, void *p)
if (lev->refcnt == 1) {
int freed = listener_decref_and_unlock(lev);
EVUTIL_ASSERT(freed);

evutil_closesocket(new_fd);
return;
}
--lev->refcnt;
Expand Down
48 changes: 48 additions & 0 deletions test/regress_listener.c
Expand Up @@ -185,6 +185,51 @@ regress_listener_error(void *arg)
evconnlistener_free(listener);
}

static void
acceptcb_free(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int socklen, void *arg)
{
int *ptr = arg;
--*ptr;
TT_BLATHER(("Got one for %p", ptr));
evutil_closesocket(fd);

if (! *ptr)
evconnlistener_free(listener);
}
static void
regress_listener_close_accepted_fd(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
struct sockaddr_in sin;
struct sockaddr_storage ss;
ev_socklen_t slen = sizeof(ss);
int count = 1;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
int fd = -1;

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = 0; /* "You pick!" */

/* Start a listener with a bogus socket. */
listener = evconnlistener_new_bind(base, acceptcb_free, &count,
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener);

tt_assert(getsockname(evconnlistener_get_fd(listener),
(struct sockaddr*)&ss, &slen) == 0);
evutil_socket_connect_(&fd, (struct sockaddr*)&ss, slen);

event_base_dispatch(base);

end:
;
}

#ifdef EVENT__HAVE_SETRLIMIT
static void
regress_listener_error_unlock(void *arg)
Expand Down Expand Up @@ -242,6 +287,9 @@ struct testcase_t listener_testcases[] = {
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR,
&basic_setup, (char*)"ts"},

{ "close_accepted_fd", regress_listener_close_accepted_fd,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL, },

END_OF_TESTCASES,
};

Expand Down

0 comments on commit bc65ffc

Please sign in to comment.