2 * Copyright (c) 2009-2012 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 "event2/event-config.h"
28 #include "evconfig-private.h"
30 #include <sys/types.h>
34 /* Minimum required for InitializeCriticalSectionAndSpinCount */
35 #define _WIN32_WINNT 0x0403
42 #ifdef EVENT__HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
45 #ifdef EVENT__HAVE_FCNTL_H
48 #ifdef EVENT__HAVE_UNISTD_H
52 #include "event2/listener.h"
53 #include "event2/util.h"
54 #include "event2/event.h"
55 #include "event2/event_struct.h"
56 #include "mm-internal.h"
57 #include "util-internal.h"
58 #include "log-internal.h"
59 #include "evthread-internal.h"
61 #include "iocp-internal.h"
62 #include "defer-internal.h"
63 #include "event-internal.h"
66 struct evconnlistener_ops
{
67 int (*enable
)(struct evconnlistener
*);
68 int (*disable
)(struct evconnlistener
*);
69 void (*destroy
)(struct evconnlistener
*);
70 void (*shutdown
)(struct evconnlistener
*);
71 evutil_socket_t (*getfd
)(struct evconnlistener
*);
72 struct event_base
*(*getbase
)(struct evconnlistener
*);
75 struct evconnlistener
{
76 const struct evconnlistener_ops
*ops
;
79 evconnlistener_errorcb errorcb
;
87 struct evconnlistener_event
{
88 struct evconnlistener base
;
89 struct event listener
;
93 struct evconnlistener_iocp
{
94 struct evconnlistener base
;
96 struct event_base
*event_base
;
97 struct event_iocp_port
*port
;
99 unsigned shutting_down
: 1;
100 unsigned event_added
: 1;
101 struct accepting_socket
**accepting
;
105 #define LOCK(listener) EVLOCK_LOCK((listener)->lock, 0)
106 #define UNLOCK(listener) EVLOCK_UNLOCK((listener)->lock, 0)
108 struct evconnlistener
*
109 evconnlistener_new_async(struct event_base
*base
,
110 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
111 evutil_socket_t fd
); /* XXXX export this? */
113 static int event_listener_enable(struct evconnlistener
*);
114 static int event_listener_disable(struct evconnlistener
*);
115 static void event_listener_destroy(struct evconnlistener
*);
116 static evutil_socket_t
event_listener_getfd(struct evconnlistener
*);
117 static struct event_base
*event_listener_getbase(struct evconnlistener
*);
121 listener_incref_and_lock(struct evconnlistener
*listener
)
129 listener_decref_and_unlock(struct evconnlistener
*listener
)
131 int refcnt
= --listener
->refcnt
;
133 listener
->ops
->destroy(listener
);
135 EVTHREAD_FREE_LOCK(listener
->lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
144 static const struct evconnlistener_ops evconnlistener_event_ops
= {
145 event_listener_enable
,
146 event_listener_disable
,
147 event_listener_destroy
,
149 event_listener_getfd
,
150 event_listener_getbase
153 static void listener_read_cb(evutil_socket_t
, short, void *);
155 struct evconnlistener
*
156 evconnlistener_new(struct event_base
*base
,
157 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
160 struct evconnlistener_event
*lev
;
163 if (base
&& event_base_get_iocp_(base
)) {
164 const struct win32_extension_fns
*ext
=
165 event_get_win32_extension_fns_();
166 if (ext
->AcceptEx
&& ext
->GetAcceptExSockaddrs
)
167 return evconnlistener_new_async(base
, cb
, ptr
, flags
,
173 if (listen(fd
, backlog
) < 0)
175 } else if (backlog
< 0) {
176 if (listen(fd
, 128) < 0)
180 lev
= mm_calloc(1, sizeof(struct evconnlistener_event
));
184 lev
->base
.ops
= &evconnlistener_event_ops
;
186 lev
->base
.user_data
= ptr
;
187 lev
->base
.flags
= flags
;
188 lev
->base
.refcnt
= 1;
190 lev
->base
.accept4_flags
= 0;
191 if (!(flags
& LEV_OPT_LEAVE_SOCKETS_BLOCKING
))
192 lev
->base
.accept4_flags
|= EVUTIL_SOCK_NONBLOCK
;
193 if (flags
& LEV_OPT_CLOSE_ON_EXEC
)
194 lev
->base
.accept4_flags
|= EVUTIL_SOCK_CLOEXEC
;
196 if (flags
& LEV_OPT_THREADSAFE
) {
197 EVTHREAD_ALLOC_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
200 event_assign(&lev
->listener
, base
, fd
, EV_READ
|EV_PERSIST
,
201 listener_read_cb
, lev
);
203 if (!(flags
& LEV_OPT_DISABLED
))
204 evconnlistener_enable(&lev
->base
);
209 struct evconnlistener
*
210 evconnlistener_new_bind(struct event_base
*base
, evconnlistener_cb cb
,
211 void *ptr
, unsigned flags
, int backlog
, const struct sockaddr
*sa
,
214 struct evconnlistener
*listener
;
217 int family
= sa
? sa
->sa_family
: AF_UNSPEC
;
218 int socktype
= SOCK_STREAM
| EVUTIL_SOCK_NONBLOCK
;
223 if (flags
& LEV_OPT_CLOSE_ON_EXEC
)
224 socktype
|= EVUTIL_SOCK_CLOEXEC
;
226 fd
= evutil_socket_(family
, socktype
, 0);
230 if (setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, (void*)&on
, sizeof(on
))<0)
233 if (flags
& LEV_OPT_REUSEABLE
) {
234 if (evutil_make_listen_socket_reuseable(fd
) < 0)
238 if (flags
& LEV_OPT_REUSEABLE_PORT
) {
239 if (evutil_make_listen_socket_reuseable_port(fd
) < 0)
243 if (flags
& LEV_OPT_DEFERRED_ACCEPT
) {
244 if (evutil_make_tcp_listen_socket_deferred(fd
) < 0)
249 if (bind(fd
, sa
, socklen
)<0)
253 listener
= evconnlistener_new(base
, cb
, ptr
, flags
, backlog
, fd
);
259 evutil_closesocket(fd
);
264 evconnlistener_free(struct evconnlistener
*lev
)
269 if (lev
->ops
->shutdown
)
270 lev
->ops
->shutdown(lev
);
271 listener_decref_and_unlock(lev
);
275 event_listener_destroy(struct evconnlistener
*lev
)
277 struct evconnlistener_event
*lev_e
=
278 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
280 event_del(&lev_e
->listener
);
281 if (lev
->flags
& LEV_OPT_CLOSE_ON_FREE
)
282 evutil_closesocket(event_get_fd(&lev_e
->listener
));
283 event_debug_unassign(&lev_e
->listener
);
287 evconnlistener_enable(struct evconnlistener
*lev
)
293 r
= lev
->ops
->enable(lev
);
301 evconnlistener_disable(struct evconnlistener
*lev
)
306 r
= lev
->ops
->disable(lev
);
312 event_listener_enable(struct evconnlistener
*lev
)
314 struct evconnlistener_event
*lev_e
=
315 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
316 return event_add(&lev_e
->listener
, NULL
);
320 event_listener_disable(struct evconnlistener
*lev
)
322 struct evconnlistener_event
*lev_e
=
323 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
324 return event_del(&lev_e
->listener
);
328 evconnlistener_get_fd(struct evconnlistener
*lev
)
332 fd
= lev
->ops
->getfd(lev
);
337 static evutil_socket_t
338 event_listener_getfd(struct evconnlistener
*lev
)
340 struct evconnlistener_event
*lev_e
=
341 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
342 return event_get_fd(&lev_e
->listener
);
346 evconnlistener_get_base(struct evconnlistener
*lev
)
348 struct event_base
*base
;
350 base
= lev
->ops
->getbase(lev
);
355 static struct event_base
*
356 event_listener_getbase(struct evconnlistener
*lev
)
358 struct evconnlistener_event
*lev_e
=
359 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
360 return event_get_base(&lev_e
->listener
);
364 evconnlistener_set_cb(struct evconnlistener
*lev
,
365 evconnlistener_cb cb
, void *arg
)
369 if (lev
->enabled
&& !lev
->cb
)
372 lev
->user_data
= arg
;
374 evconnlistener_enable(lev
);
379 evconnlistener_set_error_cb(struct evconnlistener
*lev
,
380 evconnlistener_errorcb errorcb
)
383 lev
->errorcb
= errorcb
;
388 listener_read_cb(evutil_socket_t fd
, short what
, void *p
)
390 struct evconnlistener
*lev
= p
;
392 evconnlistener_cb cb
;
393 evconnlistener_errorcb errorcb
;
397 struct sockaddr_storage ss
;
398 ev_socklen_t socklen
= sizeof(ss
);
399 evutil_socket_t new_fd
= evutil_accept4_(fd
, (struct sockaddr
*)&ss
, &socklen
, lev
->accept4_flags
);
403 /* This can happen with some older linux kernels in
404 * response to nmap. */
405 evutil_closesocket(new_fd
);
409 if (lev
->cb
== NULL
) {
410 evutil_closesocket(new_fd
);
416 user_data
= lev
->user_data
;
418 cb(lev
, new_fd
, (struct sockaddr
*)&ss
, (int)socklen
,
421 if (lev
->refcnt
== 1) {
422 int freed
= listener_decref_and_unlock(lev
);
423 EVUTIL_ASSERT(freed
);
425 evutil_closesocket(new_fd
);
430 err
= evutil_socket_geterror(fd
);
431 if (EVUTIL_ERR_ACCEPT_RETRIABLE(err
)) {
435 if (lev
->errorcb
!= NULL
) {
437 errorcb
= lev
->errorcb
;
438 user_data
= lev
->user_data
;
440 errorcb(lev
, user_data
);
442 listener_decref_and_unlock(lev
);
444 event_sock_warn(fd
, "Error from accept() call");
449 struct accepting_socket
{
450 CRITICAL_SECTION lock
;
451 struct event_overlapped overlapped
;
454 struct event_callback deferred
;
455 struct evconnlistener_iocp
*lev
;
458 unsigned free_on_cb
:1;
462 static void accepted_socket_cb(struct event_overlapped
*o
, ev_uintptr_t key
,
463 ev_ssize_t n
, int ok
);
464 static void accepted_socket_invoke_user_cb(struct event_callback
*cb
, void *arg
);
467 iocp_listener_event_add(struct evconnlistener_iocp
*lev
)
469 if (lev
->event_added
)
472 lev
->event_added
= 1;
473 event_base_add_virtual_(lev
->event_base
);
477 iocp_listener_event_del(struct evconnlistener_iocp
*lev
)
479 if (!lev
->event_added
)
482 lev
->event_added
= 0;
483 event_base_del_virtual_(lev
->event_base
);
486 static struct accepting_socket
*
487 new_accepting_socket(struct evconnlistener_iocp
*lev
, int family
)
489 struct accepting_socket
*res
;
493 if (family
== AF_INET
)
494 addrlen
= sizeof(struct sockaddr_in
);
495 else if (family
== AF_INET6
)
496 addrlen
= sizeof(struct sockaddr_in6
);
499 buflen
= (addrlen
+16)*2;
501 res
= mm_calloc(1,sizeof(struct accepting_socket
)-1+buflen
);
505 event_overlapped_init_(&res
->overlapped
, accepted_socket_cb
);
506 res
->s
= INVALID_SOCKET
;
508 res
->buflen
= buflen
;
509 res
->family
= family
;
511 event_deferred_cb_init_(&res
->deferred
,
512 event_base_get_npriorities(lev
->event_base
) / 2,
513 accepted_socket_invoke_user_cb
, res
);
515 InitializeCriticalSectionAndSpinCount(&res
->lock
, 1000);
521 free_and_unlock_accepting_socket(struct accepting_socket
*as
)
524 if (as
->s
!= INVALID_SOCKET
)
527 LeaveCriticalSection(&as
->lock
);
528 DeleteCriticalSection(&as
->lock
);
533 start_accepting(struct accepting_socket
*as
)
536 const struct win32_extension_fns
*ext
= event_get_win32_extension_fns_();
538 SOCKET s
= socket(as
->family
, SOCK_STREAM
, 0);
541 if (!as
->lev
->base
.enabled
)
544 if (s
== INVALID_SOCKET
) {
545 error
= WSAGetLastError();
549 /* XXXX It turns out we need to do this again later. Does this call
550 * have any effect? */
551 setsockopt(s
, SOL_SOCKET
, SO_UPDATE_ACCEPT_CONTEXT
,
552 (char *)&as
->lev
->fd
, sizeof(&as
->lev
->fd
));
554 if (!(as
->lev
->base
.flags
& LEV_OPT_LEAVE_SOCKETS_BLOCKING
))
555 evutil_make_socket_nonblocking(s
);
557 if (event_iocp_port_associate_(as
->lev
->port
, s
, 1) < 0) {
564 if (ext
->AcceptEx(as
->lev
->fd
, s
, as
->addrbuf
, 0,
565 as
->buflen
/2, as
->buflen
/2, &pending
, &as
->overlapped
.overlapped
))
567 /* Immediate success! */
568 accepted_socket_cb(&as
->overlapped
, 1, 0, 1);
570 error
= WSAGetLastError();
571 if (error
!= ERROR_IO_PENDING
) {
580 event_deferred_cb_schedule_(
587 stop_accepting(struct accepting_socket
*as
)
591 as
->s
= INVALID_SOCKET
;
596 accepted_socket_invoke_user_cb(struct event_callback
*dcb
, void *arg
)
598 struct accepting_socket
*as
= arg
;
600 struct sockaddr
*sa_local
=NULL
, *sa_remote
=NULL
;
601 int socklen_local
=0, socklen_remote
=0;
602 const struct win32_extension_fns
*ext
= event_get_win32_extension_fns_();
603 struct evconnlistener
*lev
= &as
->lev
->base
;
604 evutil_socket_t sock
=-1;
606 evconnlistener_cb cb
=NULL
;
607 evconnlistener_errorcb errorcb
=NULL
;
610 EVUTIL_ASSERT(ext
->GetAcceptExSockaddrs
);
613 EnterCriticalSection(&as
->lock
);
614 if (as
->free_on_cb
) {
615 free_and_unlock_accepting_socket(as
);
616 listener_decref_and_unlock(lev
);
625 errorcb
= lev
->errorcb
;
627 ext
->GetAcceptExSockaddrs(
628 as
->addrbuf
, 0, as
->buflen
/2, as
->buflen
/2,
629 &sa_local
, &socklen_local
, &sa_remote
,
633 as
->s
= INVALID_SOCKET
;
635 /* We need to call this so getsockname, getpeername, and
636 * shutdown work correctly on the accepted socket. */
637 /* XXXX handle error? */
638 setsockopt(sock
, SOL_SOCKET
, SO_UPDATE_ACCEPT_CONTEXT
,
639 (char *)&as
->lev
->fd
, sizeof(&as
->lev
->fd
));
641 data
= lev
->user_data
;
643 LeaveCriticalSection(&as
->lock
);
647 WSASetLastError(error
);
650 cb(lev
, sock
, sa_remote
, socklen_remote
, data
);
654 if (listener_decref_and_unlock(lev
))
657 EnterCriticalSection(&as
->lock
);
659 LeaveCriticalSection(&as
->lock
);
663 accepted_socket_cb(struct event_overlapped
*o
, ev_uintptr_t key
, ev_ssize_t n
, int ok
)
665 struct accepting_socket
*as
=
666 EVUTIL_UPCAST(o
, struct accepting_socket
, overlapped
);
668 LOCK(&as
->lev
->base
);
669 EnterCriticalSection(&as
->lock
);
671 /* XXXX Don't do this if some EV_MT flag is set. */
672 event_deferred_cb_schedule_(
675 LeaveCriticalSection(&as
->lock
);
676 } else if (as
->free_on_cb
) {
677 struct evconnlistener
*lev
= &as
->lev
->base
;
678 free_and_unlock_accepting_socket(as
);
679 listener_decref_and_unlock(lev
);
681 } else if (as
->s
== INVALID_SOCKET
) {
682 /* This is okay; we were disabled by iocp_listener_disable. */
683 LeaveCriticalSection(&as
->lock
);
685 /* Some error on accept that we couldn't actually handle. */
687 DWORD transfer
= 0, flags
=0;
688 event_sock_warn(as
->s
, "Unexpected error on AcceptEx");
689 ok
= WSAGetOverlappedResult(as
->s
, &o
->overlapped
,
690 &transfer
, FALSE
, &flags
);
692 /* well, that was confusing! */
695 as
->error
= WSAGetLastError();
697 event_deferred_cb_schedule_(
700 LeaveCriticalSection(&as
->lock
);
702 UNLOCK(&as
->lev
->base
);
706 iocp_listener_enable(struct evconnlistener
*lev
)
709 struct evconnlistener_iocp
*lev_iocp
=
710 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
713 iocp_listener_event_add(lev_iocp
);
714 for (i
= 0; i
< lev_iocp
->n_accepting
; ++i
) {
715 struct accepting_socket
*as
= lev_iocp
->accepting
[i
];
718 EnterCriticalSection(&as
->lock
);
719 if (!as
->free_on_cb
&& as
->s
== INVALID_SOCKET
)
721 LeaveCriticalSection(&as
->lock
);
728 iocp_listener_disable_impl(struct evconnlistener
*lev
, int shutdown
)
731 struct evconnlistener_iocp
*lev_iocp
=
732 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
735 iocp_listener_event_del(lev_iocp
);
736 for (i
= 0; i
< lev_iocp
->n_accepting
; ++i
) {
737 struct accepting_socket
*as
= lev_iocp
->accepting
[i
];
740 EnterCriticalSection(&as
->lock
);
741 if (!as
->free_on_cb
&& as
->s
!= INVALID_SOCKET
) {
746 LeaveCriticalSection(&as
->lock
);
749 if (shutdown
&& lev
->flags
& LEV_OPT_CLOSE_ON_FREE
)
750 evutil_closesocket(lev_iocp
->fd
);
757 iocp_listener_disable(struct evconnlistener
*lev
)
759 return iocp_listener_disable_impl(lev
,0);
763 iocp_listener_destroy(struct evconnlistener
*lev
)
765 struct evconnlistener_iocp
*lev_iocp
=
766 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
768 if (! lev_iocp
->shutting_down
) {
769 lev_iocp
->shutting_down
= 1;
770 iocp_listener_disable_impl(lev
,1);
775 static evutil_socket_t
776 iocp_listener_getfd(struct evconnlistener
*lev
)
778 struct evconnlistener_iocp
*lev_iocp
=
779 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
782 static struct event_base
*
783 iocp_listener_getbase(struct evconnlistener
*lev
)
785 struct evconnlistener_iocp
*lev_iocp
=
786 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
787 return lev_iocp
->event_base
;
790 static const struct evconnlistener_ops evconnlistener_iocp_ops
= {
791 iocp_listener_enable
,
792 iocp_listener_disable
,
793 iocp_listener_destroy
,
794 iocp_listener_destroy
, /* shutdown */
796 iocp_listener_getbase
799 /* XXX define some way to override this. */
800 #define N_SOCKETS_PER_LISTENER 4
802 struct evconnlistener
*
803 evconnlistener_new_async(struct event_base
*base
,
804 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
807 struct sockaddr_storage ss
;
808 int socklen
= sizeof(ss
);
809 struct evconnlistener_iocp
*lev
;
812 flags
|= LEV_OPT_THREADSAFE
;
814 if (!base
|| !event_base_get_iocp_(base
))
817 /* XXXX duplicate code */
819 if (listen(fd
, backlog
) < 0)
821 } else if (backlog
< 0) {
822 if (listen(fd
, 128) < 0)
825 if (getsockname(fd
, (struct sockaddr
*)&ss
, &socklen
)) {
826 event_sock_warn(fd
, "getsockname");
829 lev
= mm_calloc(1, sizeof(struct evconnlistener_iocp
));
831 event_warn("calloc");
834 lev
->base
.ops
= &evconnlistener_iocp_ops
;
836 lev
->base
.user_data
= ptr
;
837 lev
->base
.flags
= flags
;
838 lev
->base
.refcnt
= 1;
839 lev
->base
.enabled
= 1;
841 lev
->port
= event_base_get_iocp_(base
);
843 lev
->event_base
= base
;
846 if (event_iocp_port_associate_(lev
->port
, fd
, 1) < 0)
849 EVTHREAD_ALLOC_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
851 lev
->n_accepting
= N_SOCKETS_PER_LISTENER
;
852 lev
->accepting
= mm_calloc(lev
->n_accepting
,
853 sizeof(struct accepting_socket
*));
854 if (!lev
->accepting
) {
855 event_warn("calloc");
856 goto err_delete_lock
;
858 for (i
= 0; i
< lev
->n_accepting
; ++i
) {
859 lev
->accepting
[i
] = new_accepting_socket(lev
, ss
.ss_family
);
860 if (!lev
->accepting
[i
]) {
861 event_warnx("Couldn't create accepting socket");
862 goto err_free_accepting
;
864 if (cb
&& start_accepting(lev
->accepting
[i
]) < 0) {
865 event_warnx("Couldn't start accepting on socket");
866 EnterCriticalSection(&lev
->accepting
[i
]->lock
);
867 free_and_unlock_accepting_socket(lev
->accepting
[i
]);
868 goto err_free_accepting
;
873 iocp_listener_event_add(lev
);
878 mm_free(lev
->accepting
);
879 /* XXXX free the other elements. */
881 EVTHREAD_FREE_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
885 /* Don't close the fd, it is caller's responsibility. */