summaryrefslogtreecommitdiff
path: root/listener.c
diff options
context:
space:
mode:
Diffstat (limited to 'listener.c')
-rw-r--r--listener.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/listener.c b/listener.c
index 2862d32e..387a89e9 100644
--- a/listener.c
+++ b/listener.c
@@ -245,6 +245,11 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
goto err;
}
+ if (flags & LEV_OPT_BIND_IPV6ONLY) {
+ if (evutil_make_listen_socket_ipv6only(fd) < 0)
+ goto err;
+ }
+
if (sa) {
if (bind(fd, sa, socklen)<0)
goto err;
@@ -421,11 +426,14 @@ 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;
+ if (!lev->enabled) {
+ /* the callback could have disabled the listener */
+ UNLOCK(lev);
+ return;
+ }
}
err = evutil_socket_geterror(fd);
if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) {
@@ -504,7 +512,7 @@ new_accepting_socket(struct evconnlistener_iocp *lev, int family)
return NULL;
event_overlapped_init_(&res->overlapped, accepted_socket_cb);
- res->s = INVALID_SOCKET;
+ res->s = EVUTIL_INVALID_SOCKET;
res->lev = lev;
res->buflen = buflen;
res->family = family;
@@ -522,7 +530,7 @@ static void
free_and_unlock_accepting_socket(struct accepting_socket *as)
{
/* requires lock. */
- if (as->s != INVALID_SOCKET)
+ if (as->s != EVUTIL_INVALID_SOCKET)
closesocket(as->s);
LeaveCriticalSection(&as->lock);
@@ -542,7 +550,7 @@ start_accepting(struct accepting_socket *as)
if (!as->lev->base.enabled)
return 0;
- if (s == INVALID_SOCKET) {
+ if (s == EVUTIL_INVALID_SOCKET) {
error = WSAGetLastError();
goto report_err;
}
@@ -589,7 +597,7 @@ stop_accepting(struct accepting_socket *as)
{
/* requires lock. */
SOCKET s = as->s;
- as->s = INVALID_SOCKET;
+ as->s = EVUTIL_INVALID_SOCKET;
closesocket(s);
}
@@ -631,7 +639,7 @@ accepted_socket_invoke_user_cb(struct event_callback *dcb, void *arg)
&socklen_remote);
sock = as->s;
cb = lev->cb;
- as->s = INVALID_SOCKET;
+ as->s = EVUTIL_INVALID_SOCKET;
/* We need to call this so getsockname, getpeername, and
* shutdown work correctly on the accepted socket. */
@@ -679,7 +687,7 @@ accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, i
free_and_unlock_accepting_socket(as);
listener_decref_and_unlock(lev);
return;
- } else if (as->s == INVALID_SOCKET) {
+ } else if (as->s == EVUTIL_INVALID_SOCKET) {
/* This is okay; we were disabled by iocp_listener_disable. */
LeaveCriticalSection(&as->lock);
} else {
@@ -717,7 +725,7 @@ iocp_listener_enable(struct evconnlistener *lev)
if (!as)
continue;
EnterCriticalSection(&as->lock);
- if (!as->free_on_cb && as->s == INVALID_SOCKET)
+ if (!as->free_on_cb && as->s == EVUTIL_INVALID_SOCKET)
start_accepting(as);
LeaveCriticalSection(&as->lock);
}
@@ -739,7 +747,7 @@ iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown)
if (!as)
continue;
EnterCriticalSection(&as->lock);
- if (!as->free_on_cb && as->s != INVALID_SOCKET) {
+ if (!as->free_on_cb && as->s != EVUTIL_INVALID_SOCKET) {
if (shutdown)
as->free_on_cb = 1;
stop_accepting(as);