2 * Copyright (c) 2009-2010 Niels Provos, Nick Mathewson
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/types.h>
29 #include "event2/event-config.h"
37 #ifdef _EVENT_HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
40 #ifdef _EVENT_HAVE_FCNTL_H
43 #ifdef _EVENT_HAVE_UNISTD_H
47 #include "event2/listener.h"
48 #include "event2/util.h"
49 #include "event2/event.h"
50 #include "event2/event_struct.h"
51 #include "mm-internal.h"
52 #include "util-internal.h"
53 #include "log-internal.h"
54 #include "evthread-internal.h"
56 #include "iocp-internal.h"
57 #include "defer-internal.h"
58 #include "event-internal.h"
61 struct evconnlistener_ops {
62 int (*enable)(struct evconnlistener *);
63 int (*disable)(struct evconnlistener *);
64 void (*destroy)(struct evconnlistener *);
65 void (*shutdown)(struct evconnlistener *);
66 evutil_socket_t (*getfd)(struct evconnlistener *);
67 struct event_base *(*getbase)(struct evconnlistener *);
70 struct evconnlistener {
71 const struct evconnlistener_ops *ops;
74 evconnlistener_errorcb errorcb;
81 struct evconnlistener_event {
82 struct evconnlistener base;
83 struct event listener;
87 struct evconnlistener_iocp {
88 struct evconnlistener base;
90 struct event_base *event_base;
91 struct event_iocp_port *port;
93 unsigned shutting_down : 1;
94 unsigned event_added : 1;
95 struct accepting_socket **accepting;
99 #define LOCK(listener) EVLOCK_LOCK((listener)->lock, 0)
100 #define UNLOCK(listener) EVLOCK_UNLOCK((listener)->lock, 0)
102 struct evconnlistener *
103 evconnlistener_new_async(struct event_base *base,
104 evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
105 evutil_socket_t fd); /* XXXX export this? */
107 static int event_listener_enable(struct evconnlistener *);
108 static int event_listener_disable(struct evconnlistener *);
109 static void event_listener_destroy(struct evconnlistener *);
110 static evutil_socket_t event_listener_getfd(struct evconnlistener *);
111 static struct event_base *event_listener_getbase(struct evconnlistener *);
115 listener_incref_and_lock(struct evconnlistener *listener)
123 listener_decref_and_unlock(struct evconnlistener *listener)
125 int refcnt = --listener->refcnt;
127 listener->ops->destroy(listener);
129 EVTHREAD_FREE_LOCK(listener->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
138 static const struct evconnlistener_ops evconnlistener_event_ops = {
139 event_listener_enable,
140 event_listener_disable,
141 event_listener_destroy,
143 event_listener_getfd,
144 event_listener_getbase
147 static void listener_read_cb(evutil_socket_t, short, void *);
149 struct evconnlistener *
150 evconnlistener_new(struct event_base *base,
151 evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
154 struct evconnlistener_event *lev;
157 if (base && event_base_get_iocp(base)) {
158 const struct win32_extension_fns *ext =
159 event_get_win32_extension_fns();
160 if (ext->AcceptEx && ext->GetAcceptExSockaddrs)
161 return evconnlistener_new_async(base, cb, ptr, flags,
167 if (listen(fd, backlog) < 0)
169 } else if (backlog < 0) {
170 if (listen(fd, 128) < 0)
174 lev = mm_calloc(1, sizeof(struct evconnlistener_event));
178 lev->base.ops = &evconnlistener_event_ops;
180 lev->base.user_data = ptr;
181 lev->base.flags = flags;
182 lev->base.refcnt = 1;
184 if (flags & LEV_OPT_THREADSAFE) {
185 EVTHREAD_ALLOC_LOCK(lev->base.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
188 event_assign(&lev->listener, base, fd, EV_READ|EV_PERSIST,
189 listener_read_cb, lev);
191 evconnlistener_enable(&lev->base);
196 struct evconnlistener *
197 evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
198 void *ptr, unsigned flags, int backlog, const struct sockaddr *sa,
201 struct evconnlistener *listener;
204 int family = sa ? sa->sa_family : AF_UNSPEC;
209 fd = socket(family, SOCK_STREAM, 0);
213 if (evutil_make_socket_nonblocking(fd) < 0) {
214 evutil_closesocket(fd);
218 if (flags & LEV_OPT_CLOSE_ON_EXEC) {
219 if (evutil_make_socket_closeonexec(fd) < 0) {
220 evutil_closesocket(fd);
225 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on));
226 if (flags & LEV_OPT_REUSEABLE) {
227 evutil_make_listen_socket_reuseable(fd);
231 if (bind(fd, sa, socklen)<0) {
232 evutil_closesocket(fd);
237 listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd);
239 evutil_closesocket(fd);
247 evconnlistener_free(struct evconnlistener *lev)
252 if (lev->ops->shutdown)
253 lev->ops->shutdown(lev);
254 listener_decref_and_unlock(lev);
258 event_listener_destroy(struct evconnlistener *lev)
260 struct evconnlistener_event *lev_e =
261 EVUTIL_UPCAST(lev, struct evconnlistener_event, base);
263 event_del(&lev_e->listener);
264 if (lev->flags & LEV_OPT_CLOSE_ON_FREE)
265 evutil_closesocket(event_get_fd(&lev_e->listener));
266 event_debug_unassign(&lev_e->listener);
270 evconnlistener_enable(struct evconnlistener *lev)
276 r = lev->ops->enable(lev);
284 evconnlistener_disable(struct evconnlistener *lev)
289 r = lev->ops->disable(lev);
295 event_listener_enable(struct evconnlistener *lev)
297 struct evconnlistener_event *lev_e =
298 EVUTIL_UPCAST(lev, struct evconnlistener_event, base);
299 return event_add(&lev_e->listener, NULL);
303 event_listener_disable(struct evconnlistener *lev)
305 struct evconnlistener_event *lev_e =
306 EVUTIL_UPCAST(lev, struct evconnlistener_event, base);
307 return event_del(&lev_e->listener);
311 evconnlistener_get_fd(struct evconnlistener *lev)
315 fd = lev->ops->getfd(lev);
320 static evutil_socket_t
321 event_listener_getfd(struct evconnlistener *lev)
323 struct evconnlistener_event *lev_e =
324 EVUTIL_UPCAST(lev, struct evconnlistener_event, base);
325 return event_get_fd(&lev_e->listener);
329 evconnlistener_get_base(struct evconnlistener *lev)
331 struct event_base *base;
333 base = lev->ops->getbase(lev);
338 static struct event_base *
339 event_listener_getbase(struct evconnlistener *lev)
341 struct evconnlistener_event *lev_e =
342 EVUTIL_UPCAST(lev, struct evconnlistener_event, base);
343 return event_get_base(&lev_e->listener);
347 evconnlistener_set_cb(struct evconnlistener *lev,
348 evconnlistener_cb cb, void *arg)
352 if (lev->enabled && !lev->cb)
355 lev->user_data = arg;
357 evconnlistener_enable(lev);
362 evconnlistener_set_error_cb(struct evconnlistener *lev,
363 evconnlistener_errorcb errorcb)
366 lev->errorcb = errorcb;
371 listener_read_cb(evutil_socket_t fd, short what, void *p)
373 struct evconnlistener *lev = p;
375 evconnlistener_cb cb;
376 evconnlistener_errorcb errorcb;
380 struct sockaddr_storage ss;
382 int socklen = sizeof(ss);
384 socklen_t socklen = sizeof(ss);
386 evutil_socket_t new_fd = accept(fd, (struct sockaddr*)&ss, &socklen);
390 if (!(lev->flags & LEV_OPT_LEAVE_SOCKETS_BLOCKING))
391 evutil_make_socket_nonblocking(new_fd);
393 if (lev->cb == NULL) {
399 user_data = lev->user_data;
401 cb(lev, new_fd, (struct sockaddr*)&ss, (int)socklen,
404 if (lev->refcnt == 1) {
405 int freed = listener_decref_and_unlock(lev);
406 EVUTIL_ASSERT(freed);
411 err = evutil_socket_geterror(fd);
412 if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) {
416 if (lev->errorcb != NULL) {
418 errorcb = lev->errorcb;
419 user_data = lev->user_data;
421 errorcb(lev, user_data);
423 listener_decref_and_unlock(lev);
425 event_sock_warn(fd, "Error from accept() call");
430 struct accepting_socket {
431 CRITICAL_SECTION lock;
432 struct event_overlapped overlapped;
435 struct deferred_cb deferred;
436 struct evconnlistener_iocp *lev;
439 unsigned free_on_cb:1;
443 static void accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key,
444 ev_ssize_t n, int ok);
445 static void accepted_socket_invoke_user_cb(struct deferred_cb *cb, void *arg);
448 iocp_listener_event_add(struct evconnlistener_iocp *lev)
450 if (lev->event_added)
453 lev->event_added = 1;
454 event_base_add_virtual(lev->event_base);
458 iocp_listener_event_del(struct evconnlistener_iocp *lev)
460 if (!lev->event_added)
463 lev->event_added = 0;
464 event_base_del_virtual(lev->event_base);
467 static struct accepting_socket *
468 new_accepting_socket(struct evconnlistener_iocp *lev, int family)
470 struct accepting_socket *res;
474 if (family == AF_INET)
475 addrlen = sizeof(struct sockaddr_in);
476 else if (family == AF_INET6)
477 addrlen = sizeof(struct sockaddr_in6);
480 buflen = (addrlen+16)*2;
482 res = mm_calloc(1,sizeof(struct accepting_socket)-1+buflen);
486 event_overlapped_init(&res->overlapped, accepted_socket_cb);
487 res->s = INVALID_SOCKET;
489 res->buflen = buflen;
490 res->family = family;
492 event_deferred_cb_init(&res->deferred,
493 accepted_socket_invoke_user_cb, res);
495 InitializeCriticalSectionAndSpinCount(&res->lock, 1000);
501 free_and_unlock_accepting_socket(struct accepting_socket *as)
504 if (as->s != INVALID_SOCKET)
507 LeaveCriticalSection(&as->lock);
508 DeleteCriticalSection(&as->lock);
513 start_accepting(struct accepting_socket *as)
516 const struct win32_extension_fns *ext = event_get_win32_extension_fns();
518 SOCKET s = socket(as->family, SOCK_STREAM, 0);
521 if (!as->lev->base.enabled)
524 if (s == INVALID_SOCKET) {
525 error = WSAGetLastError();
529 /* XXXX It turns out we need to do this again later. Does this call
530 * have any effect? */
531 setsockopt(s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
532 (char *)&as->lev->fd, sizeof(&as->lev->fd));
534 if (!(as->lev->base.flags & LEV_OPT_LEAVE_SOCKETS_BLOCKING))
535 evutil_make_socket_nonblocking(s);
537 if (event_iocp_port_associate(as->lev->port, s, 1) < 0) {
544 if (ext->AcceptEx(as->lev->fd, s, as->addrbuf, 0,
545 as->buflen/2, as->buflen/2, &pending, &as->overlapped.overlapped))
547 /* Immediate success! */
548 accepted_socket_cb(&as->overlapped, 1, 0, 1);
550 error = WSAGetLastError();
551 if (error != ERROR_IO_PENDING) {
560 event_deferred_cb_schedule(
561 event_base_get_deferred_cb_queue(as->lev->event_base),
567 stop_accepting(struct accepting_socket *as)
571 as->s = INVALID_SOCKET;
576 accepted_socket_invoke_user_cb(struct deferred_cb *dcb, void *arg)
578 struct accepting_socket *as = arg;
580 struct sockaddr *sa_local=NULL, *sa_remote=NULL;
581 int socklen_local=0, socklen_remote=0;
582 const struct win32_extension_fns *ext = event_get_win32_extension_fns();
583 struct evconnlistener *lev = &as->lev->base;
584 evutil_socket_t sock=-1;
586 evconnlistener_cb cb=NULL;
587 evconnlistener_errorcb errorcb=NULL;
590 EVUTIL_ASSERT(ext->GetAcceptExSockaddrs);
593 EnterCriticalSection(&as->lock);
594 if (as->free_on_cb) {
595 free_and_unlock_accepting_socket(as);
596 listener_decref_and_unlock(lev);
605 errorcb = lev->errorcb;
607 ext->GetAcceptExSockaddrs(
608 as->addrbuf, 0, as->buflen/2, as->buflen/2,
609 &sa_local, &socklen_local, &sa_remote,
613 as->s = INVALID_SOCKET;
615 /* We need to call this so getsockname, getpeername, and
616 * shutdown work correctly on the accepted socket. */
617 /* XXXX handle error? */
618 setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
619 (char *)&as->lev->fd, sizeof(&as->lev->fd));
621 data = lev->user_data;
623 LeaveCriticalSection(&as->lock);
627 WSASetLastError(error);
630 cb(lev, sock, sa_remote, socklen_remote, data);
634 if (listener_decref_and_unlock(lev))
637 EnterCriticalSection(&as->lock);
639 LeaveCriticalSection(&as->lock);
643 accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, int ok)
645 struct accepting_socket *as =
646 EVUTIL_UPCAST(o, struct accepting_socket, overlapped);
648 LOCK(&as->lev->base);
649 EnterCriticalSection(&as->lock);
651 /* XXXX Don't do this if some EV_MT flag is set. */
652 event_deferred_cb_schedule(
653 event_base_get_deferred_cb_queue(as->lev->event_base),
655 LeaveCriticalSection(&as->lock);
656 } else if (as->free_on_cb) {
657 struct evconnlistener *lev = &as->lev->base;
658 free_and_unlock_accepting_socket(as);
659 listener_decref_and_unlock(lev);
661 } else if (as->s == INVALID_SOCKET) {
662 /* This is okay; we were disabled by iocp_listener_disable. */
663 LeaveCriticalSection(&as->lock);
665 /* Some error on accept that we couldn't actually handle. */
667 DWORD transfer = 0, flags=0;
668 event_sock_warn(as->s, "Unexpected error on AcceptEx");
669 ok = WSAGetOverlappedResult(as->s, &o->overlapped,
670 &transfer, FALSE, &flags);
672 /* well, that was confusing! */
675 as->error = WSAGetLastError();
677 event_deferred_cb_schedule(
678 event_base_get_deferred_cb_queue(as->lev->event_base),
680 LeaveCriticalSection(&as->lock);
682 UNLOCK(&as->lev->base);
686 iocp_listener_enable(struct evconnlistener *lev)
689 struct evconnlistener_iocp *lev_iocp =
690 EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
693 iocp_listener_event_add(lev_iocp);
694 for (i = 0; i < lev_iocp->n_accepting; ++i) {
695 struct accepting_socket *as = lev_iocp->accepting[i];
698 EnterCriticalSection(&as->lock);
699 if (!as->free_on_cb && as->s == INVALID_SOCKET)
701 LeaveCriticalSection(&as->lock);
708 iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown)
711 struct evconnlistener_iocp *lev_iocp =
712 EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
715 iocp_listener_event_del(lev_iocp);
716 for (i = 0; i < lev_iocp->n_accepting; ++i) {
717 struct accepting_socket *as = lev_iocp->accepting[i];
720 EnterCriticalSection(&as->lock);
721 if (!as->free_on_cb && as->s != INVALID_SOCKET) {
726 LeaveCriticalSection(&as->lock);
733 iocp_listener_disable(struct evconnlistener *lev)
735 return iocp_listener_disable_impl(lev,0);
739 iocp_listener_destroy(struct evconnlistener *lev)
741 struct evconnlistener_iocp *lev_iocp =
742 EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
744 if (! lev_iocp->shutting_down) {
745 lev_iocp->shutting_down = 1;
746 iocp_listener_disable_impl(lev,1);
751 static evutil_socket_t
752 iocp_listener_getfd(struct evconnlistener *lev)
754 struct evconnlistener_iocp *lev_iocp =
755 EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
758 static struct event_base *
759 iocp_listener_getbase(struct evconnlistener *lev)
761 struct evconnlistener_iocp *lev_iocp =
762 EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
763 return lev_iocp->event_base;
766 static const struct evconnlistener_ops evconnlistener_iocp_ops = {
767 iocp_listener_enable,
768 iocp_listener_disable,
769 iocp_listener_destroy,
770 iocp_listener_destroy, /* shutdown */
772 iocp_listener_getbase
775 /* XXX define some way to override this. */
776 #define N_SOCKETS_PER_LISTENER 4
778 struct evconnlistener *
779 evconnlistener_new_async(struct event_base *base,
780 evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
783 struct sockaddr_storage ss;
784 int socklen = sizeof(ss);
785 struct evconnlistener_iocp *lev;
788 flags |= LEV_OPT_THREADSAFE;
790 if (!base || !event_base_get_iocp(base))
793 /* XXXX duplicate code */
795 if (listen(fd, backlog) < 0)
797 } else if (backlog < 0) {
798 if (listen(fd, 128) < 0)
801 if (getsockname(fd, (struct sockaddr*)&ss, &socklen)) {
802 event_sock_warn(fd, "getsockname");
805 lev = mm_calloc(1, sizeof(struct evconnlistener_iocp));
807 event_warn("calloc");
810 lev->base.ops = &evconnlistener_iocp_ops;
812 lev->base.user_data = ptr;
813 lev->base.flags = flags;
814 lev->base.refcnt = 1;
815 lev->base.enabled = 1;
817 lev->port = event_base_get_iocp(base);
819 lev->event_base = base;
822 if (event_iocp_port_associate(lev->port, fd, 1) < 0)
825 EVTHREAD_ALLOC_LOCK(lev->base.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
827 lev->n_accepting = N_SOCKETS_PER_LISTENER;
828 lev->accepting = mm_calloc(lev->n_accepting,
829 sizeof(struct accepting_socket *));
830 if (!lev->accepting) {
831 event_warn("calloc");
832 goto err_delete_lock;
834 for (i = 0; i < lev->n_accepting; ++i) {
835 lev->accepting[i] = new_accepting_socket(lev, ss.ss_family);
836 if (!lev->accepting[i]) {
837 event_warnx("Couldn't create accepting socket");
838 goto err_free_accepting;
840 if (cb && start_accepting(lev->accepting[i]) < 0) {
841 event_warnx("Couldn't start accepting on socket");
842 EnterCriticalSection(&lev->accepting[i]->lock);
843 free_and_unlock_accepting_socket(lev->accepting[i]);
844 goto err_free_accepting;
849 iocp_listener_event_add(lev);
854 mm_free(lev->accepting);
855 /* XXXX free the other elements. */
857 EVTHREAD_FREE_LOCK(lev->base.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
861 /* Don't close the fd, it is caller's responsibility. */