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 <sys/types.h>
29 #include "event2/event-config.h"
33 /* Minimum required for InitializeCriticalSectionAndSpinCount */
34 #define _WIN32_WINNT 0x0403
41 #ifdef _EVENT_HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
44 #ifdef _EVENT_HAVE_FCNTL_H
47 #ifdef _EVENT_HAVE_UNISTD_H
51 #include "event2/listener.h"
52 #include "event2/util.h"
53 #include "event2/event.h"
54 #include "event2/event_struct.h"
55 #include "mm-internal.h"
56 #include "util-internal.h"
57 #include "log-internal.h"
58 #include "evthread-internal.h"
60 #include "iocp-internal.h"
61 #include "defer-internal.h"
62 #include "event-internal.h"
65 struct evconnlistener_ops
{
66 int (*enable
)(struct evconnlistener
*);
67 int (*disable
)(struct evconnlistener
*);
68 void (*destroy
)(struct evconnlistener
*);
69 void (*shutdown
)(struct evconnlistener
*);
70 evutil_socket_t (*getfd
)(struct evconnlistener
*);
71 struct event_base
*(*getbase
)(struct evconnlistener
*);
74 struct evconnlistener
{
75 const struct evconnlistener_ops
*ops
;
78 evconnlistener_errorcb errorcb
;
85 struct evconnlistener_event
{
86 struct evconnlistener base
;
87 struct event listener
;
91 struct evconnlistener_iocp
{
92 struct evconnlistener base
;
94 struct event_base
*event_base
;
95 struct event_iocp_port
*port
;
97 unsigned shutting_down
: 1;
98 unsigned event_added
: 1;
99 struct accepting_socket
**accepting
;
103 #define LOCK(listener) EVLOCK_LOCK((listener)->lock, 0)
104 #define UNLOCK(listener) EVLOCK_UNLOCK((listener)->lock, 0)
106 struct evconnlistener
*
107 evconnlistener_new_async(struct event_base
*base
,
108 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
109 evutil_socket_t fd
); /* XXXX export this? */
111 static int event_listener_enable(struct evconnlistener
*);
112 static int event_listener_disable(struct evconnlistener
*);
113 static void event_listener_destroy(struct evconnlistener
*);
114 static evutil_socket_t
event_listener_getfd(struct evconnlistener
*);
115 static struct event_base
*event_listener_getbase(struct evconnlistener
*);
119 listener_incref_and_lock(struct evconnlistener
*listener
)
127 listener_decref_and_unlock(struct evconnlistener
*listener
)
129 int refcnt
= --listener
->refcnt
;
131 listener
->ops
->destroy(listener
);
133 EVTHREAD_FREE_LOCK(listener
->lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
142 static const struct evconnlistener_ops evconnlistener_event_ops
= {
143 event_listener_enable
,
144 event_listener_disable
,
145 event_listener_destroy
,
147 event_listener_getfd
,
148 event_listener_getbase
151 static void listener_read_cb(evutil_socket_t
, short, void *);
153 struct evconnlistener
*
154 evconnlistener_new(struct event_base
*base
,
155 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
158 struct evconnlistener_event
*lev
;
161 if (base
&& event_base_get_iocp(base
)) {
162 const struct win32_extension_fns
*ext
=
163 event_get_win32_extension_fns();
164 if (ext
->AcceptEx
&& ext
->GetAcceptExSockaddrs
)
165 return evconnlistener_new_async(base
, cb
, ptr
, flags
,
171 if (listen(fd
, backlog
) < 0)
173 } else if (backlog
< 0) {
174 if (listen(fd
, 128) < 0)
178 lev
= mm_calloc(1, sizeof(struct evconnlistener_event
));
182 lev
->base
.ops
= &evconnlistener_event_ops
;
184 lev
->base
.user_data
= ptr
;
185 lev
->base
.flags
= flags
;
186 lev
->base
.refcnt
= 1;
188 if (flags
& LEV_OPT_THREADSAFE
) {
189 EVTHREAD_ALLOC_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
192 event_assign(&lev
->listener
, base
, fd
, EV_READ
|EV_PERSIST
,
193 listener_read_cb
, lev
);
195 evconnlistener_enable(&lev
->base
);
200 struct evconnlistener
*
201 evconnlistener_new_bind(struct event_base
*base
, evconnlistener_cb cb
,
202 void *ptr
, unsigned flags
, int backlog
, const struct sockaddr
*sa
,
205 struct evconnlistener
*listener
;
208 int family
= sa
? sa
->sa_family
: AF_UNSPEC
;
213 fd
= socket(family
, SOCK_STREAM
, 0);
217 if (evutil_make_socket_nonblocking(fd
) < 0) {
218 evutil_closesocket(fd
);
222 if (flags
& LEV_OPT_CLOSE_ON_EXEC
) {
223 if (evutil_make_socket_closeonexec(fd
) < 0) {
224 evutil_closesocket(fd
);
229 if (setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, (void*)&on
, sizeof(on
))<0) {
230 evutil_closesocket(fd
);
233 if (flags
& LEV_OPT_REUSEABLE
) {
234 if (evutil_make_listen_socket_reuseable(fd
) < 0) {
235 evutil_closesocket(fd
);
241 if (bind(fd
, sa
, socklen
)<0) {
242 evutil_closesocket(fd
);
247 listener
= evconnlistener_new(base
, cb
, ptr
, flags
, backlog
, fd
);
249 evutil_closesocket(fd
);
257 evconnlistener_free(struct evconnlistener
*lev
)
262 if (lev
->ops
->shutdown
)
263 lev
->ops
->shutdown(lev
);
264 listener_decref_and_unlock(lev
);
268 event_listener_destroy(struct evconnlistener
*lev
)
270 struct evconnlistener_event
*lev_e
=
271 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
273 event_del(&lev_e
->listener
);
274 if (lev
->flags
& LEV_OPT_CLOSE_ON_FREE
)
275 evutil_closesocket(event_get_fd(&lev_e
->listener
));
276 event_debug_unassign(&lev_e
->listener
);
280 evconnlistener_enable(struct evconnlistener
*lev
)
286 r
= lev
->ops
->enable(lev
);
294 evconnlistener_disable(struct evconnlistener
*lev
)
299 r
= lev
->ops
->disable(lev
);
305 event_listener_enable(struct evconnlistener
*lev
)
307 struct evconnlistener_event
*lev_e
=
308 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
309 return event_add(&lev_e
->listener
, NULL
);
313 event_listener_disable(struct evconnlistener
*lev
)
315 struct evconnlistener_event
*lev_e
=
316 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
317 return event_del(&lev_e
->listener
);
321 evconnlistener_get_fd(struct evconnlistener
*lev
)
325 fd
= lev
->ops
->getfd(lev
);
330 static evutil_socket_t
331 event_listener_getfd(struct evconnlistener
*lev
)
333 struct evconnlistener_event
*lev_e
=
334 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
335 return event_get_fd(&lev_e
->listener
);
339 evconnlistener_get_base(struct evconnlistener
*lev
)
341 struct event_base
*base
;
343 base
= lev
->ops
->getbase(lev
);
348 static struct event_base
*
349 event_listener_getbase(struct evconnlistener
*lev
)
351 struct evconnlistener_event
*lev_e
=
352 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
353 return event_get_base(&lev_e
->listener
);
357 evconnlistener_set_cb(struct evconnlistener
*lev
,
358 evconnlistener_cb cb
, void *arg
)
362 if (lev
->enabled
&& !lev
->cb
)
365 lev
->user_data
= arg
;
367 evconnlistener_enable(lev
);
372 evconnlistener_set_error_cb(struct evconnlistener
*lev
,
373 evconnlistener_errorcb errorcb
)
376 lev
->errorcb
= errorcb
;
381 listener_read_cb(evutil_socket_t fd
, short what
, void *p
)
383 struct evconnlistener
*lev
= p
;
385 evconnlistener_cb cb
;
386 evconnlistener_errorcb errorcb
;
390 struct sockaddr_storage ss
;
392 int socklen
= sizeof(ss
);
394 socklen_t socklen
= sizeof(ss
);
396 evutil_socket_t new_fd
= accept(fd
, (struct sockaddr
*)&ss
, &socklen
);
400 /* This can happen with some older linux kernels in
401 * response to nmap. */
402 evutil_closesocket(new_fd
);
406 if (!(lev
->flags
& LEV_OPT_LEAVE_SOCKETS_BLOCKING
))
407 evutil_make_socket_nonblocking(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
);
428 err
= evutil_socket_geterror(fd
);
429 if (EVUTIL_ERR_ACCEPT_RETRIABLE(err
)) {
433 if (lev
->errorcb
!= NULL
) {
435 errorcb
= lev
->errorcb
;
436 user_data
= lev
->user_data
;
438 errorcb(lev
, user_data
);
440 listener_decref_and_unlock(lev
);
442 event_sock_warn(fd
, "Error from accept() call");
447 struct accepting_socket
{
448 CRITICAL_SECTION lock
;
449 struct event_overlapped overlapped
;
452 struct deferred_cb deferred
;
453 struct evconnlistener_iocp
*lev
;
456 unsigned free_on_cb
:1;
460 static void accepted_socket_cb(struct event_overlapped
*o
, ev_uintptr_t key
,
461 ev_ssize_t n
, int ok
);
462 static void accepted_socket_invoke_user_cb(struct deferred_cb
*cb
, void *arg
);
465 iocp_listener_event_add(struct evconnlistener_iocp
*lev
)
467 if (lev
->event_added
)
470 lev
->event_added
= 1;
471 event_base_add_virtual(lev
->event_base
);
475 iocp_listener_event_del(struct evconnlistener_iocp
*lev
)
477 if (!lev
->event_added
)
480 lev
->event_added
= 0;
481 event_base_del_virtual(lev
->event_base
);
484 static struct accepting_socket
*
485 new_accepting_socket(struct evconnlistener_iocp
*lev
, int family
)
487 struct accepting_socket
*res
;
491 if (family
== AF_INET
)
492 addrlen
= sizeof(struct sockaddr_in
);
493 else if (family
== AF_INET6
)
494 addrlen
= sizeof(struct sockaddr_in6
);
497 buflen
= (addrlen
+16)*2;
499 res
= mm_calloc(1,sizeof(struct accepting_socket
)-1+buflen
);
503 event_overlapped_init(&res
->overlapped
, accepted_socket_cb
);
504 res
->s
= INVALID_SOCKET
;
506 res
->buflen
= buflen
;
507 res
->family
= family
;
509 event_deferred_cb_init(&res
->deferred
,
510 accepted_socket_invoke_user_cb
, res
);
512 InitializeCriticalSectionAndSpinCount(&res
->lock
, 1000);
518 free_and_unlock_accepting_socket(struct accepting_socket
*as
)
521 if (as
->s
!= INVALID_SOCKET
)
524 LeaveCriticalSection(&as
->lock
);
525 DeleteCriticalSection(&as
->lock
);
530 start_accepting(struct accepting_socket
*as
)
533 const struct win32_extension_fns
*ext
= event_get_win32_extension_fns();
535 SOCKET s
= socket(as
->family
, SOCK_STREAM
, 0);
538 if (!as
->lev
->base
.enabled
)
541 if (s
== INVALID_SOCKET
) {
542 error
= WSAGetLastError();
546 /* XXXX It turns out we need to do this again later. Does this call
547 * have any effect? */
548 setsockopt(s
, SOL_SOCKET
, SO_UPDATE_ACCEPT_CONTEXT
,
549 (char *)&as
->lev
->fd
, sizeof(&as
->lev
->fd
));
551 if (!(as
->lev
->base
.flags
& LEV_OPT_LEAVE_SOCKETS_BLOCKING
))
552 evutil_make_socket_nonblocking(s
);
554 if (event_iocp_port_associate(as
->lev
->port
, s
, 1) < 0) {
561 if (ext
->AcceptEx(as
->lev
->fd
, s
, as
->addrbuf
, 0,
562 as
->buflen
/2, as
->buflen
/2, &pending
, &as
->overlapped
.overlapped
))
564 /* Immediate success! */
565 accepted_socket_cb(&as
->overlapped
, 1, 0, 1);
567 error
= WSAGetLastError();
568 if (error
!= ERROR_IO_PENDING
) {
577 event_deferred_cb_schedule(
578 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
584 stop_accepting(struct accepting_socket
*as
)
588 as
->s
= INVALID_SOCKET
;
593 accepted_socket_invoke_user_cb(struct deferred_cb
*dcb
, void *arg
)
595 struct accepting_socket
*as
= arg
;
597 struct sockaddr
*sa_local
=NULL
, *sa_remote
=NULL
;
598 int socklen_local
=0, socklen_remote
=0;
599 const struct win32_extension_fns
*ext
= event_get_win32_extension_fns();
600 struct evconnlistener
*lev
= &as
->lev
->base
;
601 evutil_socket_t sock
=-1;
603 evconnlistener_cb cb
=NULL
;
604 evconnlistener_errorcb errorcb
=NULL
;
607 EVUTIL_ASSERT(ext
->GetAcceptExSockaddrs
);
610 EnterCriticalSection(&as
->lock
);
611 if (as
->free_on_cb
) {
612 free_and_unlock_accepting_socket(as
);
613 listener_decref_and_unlock(lev
);
622 errorcb
= lev
->errorcb
;
624 ext
->GetAcceptExSockaddrs(
625 as
->addrbuf
, 0, as
->buflen
/2, as
->buflen
/2,
626 &sa_local
, &socklen_local
, &sa_remote
,
630 as
->s
= INVALID_SOCKET
;
632 /* We need to call this so getsockname, getpeername, and
633 * shutdown work correctly on the accepted socket. */
634 /* XXXX handle error? */
635 setsockopt(sock
, SOL_SOCKET
, SO_UPDATE_ACCEPT_CONTEXT
,
636 (char *)&as
->lev
->fd
, sizeof(&as
->lev
->fd
));
638 data
= lev
->user_data
;
640 LeaveCriticalSection(&as
->lock
);
644 WSASetLastError(error
);
647 cb(lev
, sock
, sa_remote
, socklen_remote
, data
);
651 if (listener_decref_and_unlock(lev
))
654 EnterCriticalSection(&as
->lock
);
656 LeaveCriticalSection(&as
->lock
);
660 accepted_socket_cb(struct event_overlapped
*o
, ev_uintptr_t key
, ev_ssize_t n
, int ok
)
662 struct accepting_socket
*as
=
663 EVUTIL_UPCAST(o
, struct accepting_socket
, overlapped
);
665 LOCK(&as
->lev
->base
);
666 EnterCriticalSection(&as
->lock
);
668 /* XXXX Don't do this if some EV_MT flag is set. */
669 event_deferred_cb_schedule(
670 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
672 LeaveCriticalSection(&as
->lock
);
673 } else if (as
->free_on_cb
) {
674 struct evconnlistener
*lev
= &as
->lev
->base
;
675 free_and_unlock_accepting_socket(as
);
676 listener_decref_and_unlock(lev
);
678 } else if (as
->s
== INVALID_SOCKET
) {
679 /* This is okay; we were disabled by iocp_listener_disable. */
680 LeaveCriticalSection(&as
->lock
);
682 /* Some error on accept that we couldn't actually handle. */
684 DWORD transfer
= 0, flags
=0;
685 event_sock_warn(as
->s
, "Unexpected error on AcceptEx");
686 ok
= WSAGetOverlappedResult(as
->s
, &o
->overlapped
,
687 &transfer
, FALSE
, &flags
);
689 /* well, that was confusing! */
692 as
->error
= WSAGetLastError();
694 event_deferred_cb_schedule(
695 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
697 LeaveCriticalSection(&as
->lock
);
699 UNLOCK(&as
->lev
->base
);
703 iocp_listener_enable(struct evconnlistener
*lev
)
706 struct evconnlistener_iocp
*lev_iocp
=
707 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
710 iocp_listener_event_add(lev_iocp
);
711 for (i
= 0; i
< lev_iocp
->n_accepting
; ++i
) {
712 struct accepting_socket
*as
= lev_iocp
->accepting
[i
];
715 EnterCriticalSection(&as
->lock
);
716 if (!as
->free_on_cb
&& as
->s
== INVALID_SOCKET
)
718 LeaveCriticalSection(&as
->lock
);
725 iocp_listener_disable_impl(struct evconnlistener
*lev
, int shutdown
)
728 struct evconnlistener_iocp
*lev_iocp
=
729 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
732 iocp_listener_event_del(lev_iocp
);
733 for (i
= 0; i
< lev_iocp
->n_accepting
; ++i
) {
734 struct accepting_socket
*as
= lev_iocp
->accepting
[i
];
737 EnterCriticalSection(&as
->lock
);
738 if (!as
->free_on_cb
&& as
->s
!= INVALID_SOCKET
) {
743 LeaveCriticalSection(&as
->lock
);
746 if (shutdown
&& lev
->flags
& LEV_OPT_CLOSE_ON_FREE
)
747 evutil_closesocket(lev_iocp
->fd
);
754 iocp_listener_disable(struct evconnlistener
*lev
)
756 return iocp_listener_disable_impl(lev
,0);
760 iocp_listener_destroy(struct evconnlistener
*lev
)
762 struct evconnlistener_iocp
*lev_iocp
=
763 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
765 if (! lev_iocp
->shutting_down
) {
766 lev_iocp
->shutting_down
= 1;
767 iocp_listener_disable_impl(lev
,1);
772 static evutil_socket_t
773 iocp_listener_getfd(struct evconnlistener
*lev
)
775 struct evconnlistener_iocp
*lev_iocp
=
776 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
779 static struct event_base
*
780 iocp_listener_getbase(struct evconnlistener
*lev
)
782 struct evconnlistener_iocp
*lev_iocp
=
783 EVUTIL_UPCAST(lev
, struct evconnlistener_iocp
, base
);
784 return lev_iocp
->event_base
;
787 static const struct evconnlistener_ops evconnlistener_iocp_ops
= {
788 iocp_listener_enable
,
789 iocp_listener_disable
,
790 iocp_listener_destroy
,
791 iocp_listener_destroy
, /* shutdown */
793 iocp_listener_getbase
796 /* XXX define some way to override this. */
797 #define N_SOCKETS_PER_LISTENER 4
799 struct evconnlistener
*
800 evconnlistener_new_async(struct event_base
*base
,
801 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
804 struct sockaddr_storage ss
;
805 int socklen
= sizeof(ss
);
806 struct evconnlistener_iocp
*lev
;
809 flags
|= LEV_OPT_THREADSAFE
;
811 if (!base
|| !event_base_get_iocp(base
))
814 /* XXXX duplicate code */
816 if (listen(fd
, backlog
) < 0)
818 } else if (backlog
< 0) {
819 if (listen(fd
, 128) < 0)
822 if (getsockname(fd
, (struct sockaddr
*)&ss
, &socklen
)) {
823 event_sock_warn(fd
, "getsockname");
826 lev
= mm_calloc(1, sizeof(struct evconnlistener_iocp
));
828 event_warn("calloc");
831 lev
->base
.ops
= &evconnlistener_iocp_ops
;
833 lev
->base
.user_data
= ptr
;
834 lev
->base
.flags
= flags
;
835 lev
->base
.refcnt
= 1;
836 lev
->base
.enabled
= 1;
838 lev
->port
= event_base_get_iocp(base
);
840 lev
->event_base
= base
;
843 if (event_iocp_port_associate(lev
->port
, fd
, 1) < 0)
846 EVTHREAD_ALLOC_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
848 lev
->n_accepting
= N_SOCKETS_PER_LISTENER
;
849 lev
->accepting
= mm_calloc(lev
->n_accepting
,
850 sizeof(struct accepting_socket
*));
851 if (!lev
->accepting
) {
852 event_warn("calloc");
853 goto err_delete_lock
;
855 for (i
= 0; i
< lev
->n_accepting
; ++i
) {
856 lev
->accepting
[i
] = new_accepting_socket(lev
, ss
.ss_family
);
857 if (!lev
->accepting
[i
]) {
858 event_warnx("Couldn't create accepting socket");
859 goto err_free_accepting
;
861 if (cb
&& start_accepting(lev
->accepting
[i
]) < 0) {
862 event_warnx("Couldn't start accepting on socket");
863 EnterCriticalSection(&lev
->accepting
[i
]->lock
);
864 free_and_unlock_accepting_socket(lev
->accepting
[i
]);
865 goto err_free_accepting
;
870 iocp_listener_event_add(lev
);
875 mm_free(lev
->accepting
);
876 /* XXXX free the other elements. */
878 EVTHREAD_FREE_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
882 /* Don't close the fd, it is caller's responsibility. */