1 /* $NetBSD: listener.c,v 1.1.1.2 2015/01/29 06:38:08 spz Exp $ */
3 * Copyright (c) 2009-2012 Niels Provos, Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/types.h>
30 #include "event2/event-config.h"
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: listener.c,v 1.1.1.2 2015/01/29 06:38:08 spz Exp $");
36 /* Minimum required for InitializeCriticalSectionAndSpinCount */
37 #define _WIN32_WINNT 0x0403
44 #ifdef _EVENT_HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
47 #ifdef _EVENT_HAVE_FCNTL_H
50 #ifdef _EVENT_HAVE_UNISTD_H
54 #include "event2/listener.h"
55 #include "event2/util.h"
56 #include "event2/event.h"
57 #include "event2/event_struct.h"
58 #include "mm-internal.h"
59 #include "util-internal.h"
60 #include "log-internal.h"
61 #include "evthread-internal.h"
63 #include "iocp-internal.h"
64 #include "defer-internal.h"
65 #include "event-internal.h"
68 struct evconnlistener_ops
{
69 int (*enable
)(struct evconnlistener
*);
70 int (*disable
)(struct evconnlistener
*);
71 void (*destroy
)(struct evconnlistener
*);
72 void (*shutdown
)(struct evconnlistener
*);
73 evutil_socket_t (*getfd
)(struct evconnlistener
*);
74 struct event_base
*(*getbase
)(struct evconnlistener
*);
77 struct evconnlistener
{
78 const struct evconnlistener_ops
*ops
;
81 evconnlistener_errorcb errorcb
;
88 struct evconnlistener_event
{
89 struct evconnlistener base
;
90 struct event listener
;
94 struct evconnlistener_iocp
{
95 struct evconnlistener base
;
97 struct event_base
*event_base
;
98 struct event_iocp_port
*port
;
100 unsigned shutting_down
: 1;
101 unsigned event_added
: 1;
102 struct accepting_socket
**accepting
;
106 #define LOCK(listener) EVLOCK_LOCK((listener)->lock, 0)
107 #define UNLOCK(listener) EVLOCK_UNLOCK((listener)->lock, 0)
109 struct evconnlistener
*
110 evconnlistener_new_async(struct event_base
*base
,
111 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
112 evutil_socket_t fd
); /* XXXX export this? */
114 static int event_listener_enable(struct evconnlistener
*);
115 static int event_listener_disable(struct evconnlistener
*);
116 static void event_listener_destroy(struct evconnlistener
*);
117 static evutil_socket_t
event_listener_getfd(struct evconnlistener
*);
118 static struct event_base
*event_listener_getbase(struct evconnlistener
*);
122 listener_incref_and_lock(struct evconnlistener
*listener
)
130 listener_decref_and_unlock(struct evconnlistener
*listener
)
132 int refcnt
= --listener
->refcnt
;
134 listener
->ops
->destroy(listener
);
136 EVTHREAD_FREE_LOCK(listener
->lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
145 static const struct evconnlistener_ops evconnlistener_event_ops
= {
146 event_listener_enable
,
147 event_listener_disable
,
148 event_listener_destroy
,
150 event_listener_getfd
,
151 event_listener_getbase
154 static void listener_read_cb(evutil_socket_t
, short, void *);
156 struct evconnlistener
*
157 evconnlistener_new(struct event_base
*base
,
158 evconnlistener_cb cb
, void *ptr
, unsigned flags
, int backlog
,
161 struct evconnlistener_event
*lev
;
164 if (base
&& event_base_get_iocp(base
)) {
165 const struct win32_extension_fns
*ext
=
166 event_get_win32_extension_fns();
167 if (ext
->AcceptEx
&& ext
->GetAcceptExSockaddrs
)
168 return evconnlistener_new_async(base
, cb
, ptr
, flags
,
174 if (listen(fd
, backlog
) < 0)
176 } else if (backlog
< 0) {
177 if (listen(fd
, 128) < 0)
181 lev
= mm_calloc(1, sizeof(struct evconnlistener_event
));
185 lev
->base
.ops
= &evconnlistener_event_ops
;
187 lev
->base
.user_data
= ptr
;
188 lev
->base
.flags
= flags
;
189 lev
->base
.refcnt
= 1;
191 if (flags
& LEV_OPT_THREADSAFE
) {
192 EVTHREAD_ALLOC_LOCK(lev
->base
.lock
, EVTHREAD_LOCKTYPE_RECURSIVE
);
195 event_assign(&lev
->listener
, base
, fd
, EV_READ
|EV_PERSIST
,
196 listener_read_cb
, lev
);
198 evconnlistener_enable(&lev
->base
);
203 struct evconnlistener
*
204 evconnlistener_new_bind(struct event_base
*base
, evconnlistener_cb cb
,
205 void *ptr
, unsigned flags
, int backlog
, const struct sockaddr
*sa
,
208 struct evconnlistener
*listener
;
211 int family
= sa
? sa
->sa_family
: AF_UNSPEC
;
216 fd
= socket(family
, SOCK_STREAM
, 0);
220 if (evutil_make_socket_nonblocking(fd
) < 0) {
221 evutil_closesocket(fd
);
225 if (flags
& LEV_OPT_CLOSE_ON_EXEC
) {
226 if (evutil_make_socket_closeonexec(fd
) < 0) {
227 evutil_closesocket(fd
);
232 if (setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, (void*)&on
, sizeof(on
))<0) {
233 evutil_closesocket(fd
);
236 if (flags
& LEV_OPT_REUSEABLE
) {
237 if (evutil_make_listen_socket_reuseable(fd
) < 0) {
238 evutil_closesocket(fd
);
244 if (bind(fd
, sa
, socklen
)<0) {
245 evutil_closesocket(fd
);
250 listener
= evconnlistener_new(base
, cb
, ptr
, flags
, backlog
, fd
);
252 evutil_closesocket(fd
);
260 evconnlistener_free(struct evconnlistener
*lev
)
265 if (lev
->ops
->shutdown
)
266 lev
->ops
->shutdown(lev
);
267 listener_decref_and_unlock(lev
);
271 event_listener_destroy(struct evconnlistener
*lev
)
273 struct evconnlistener_event
*lev_e
=
274 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
276 event_del(&lev_e
->listener
);
277 if (lev
->flags
& LEV_OPT_CLOSE_ON_FREE
)
278 evutil_closesocket(event_get_fd(&lev_e
->listener
));
279 event_debug_unassign(&lev_e
->listener
);
283 evconnlistener_enable(struct evconnlistener
*lev
)
289 r
= lev
->ops
->enable(lev
);
297 evconnlistener_disable(struct evconnlistener
*lev
)
302 r
= lev
->ops
->disable(lev
);
308 event_listener_enable(struct evconnlistener
*lev
)
310 struct evconnlistener_event
*lev_e
=
311 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
312 return event_add(&lev_e
->listener
, NULL
);
316 event_listener_disable(struct evconnlistener
*lev
)
318 struct evconnlistener_event
*lev_e
=
319 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
320 return event_del(&lev_e
->listener
);
324 evconnlistener_get_fd(struct evconnlistener
*lev
)
328 fd
= lev
->ops
->getfd(lev
);
333 static evutil_socket_t
334 event_listener_getfd(struct evconnlistener
*lev
)
336 struct evconnlistener_event
*lev_e
=
337 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
338 return event_get_fd(&lev_e
->listener
);
342 evconnlistener_get_base(struct evconnlistener
*lev
)
344 struct event_base
*base
;
346 base
= lev
->ops
->getbase(lev
);
351 static struct event_base
*
352 event_listener_getbase(struct evconnlistener
*lev
)
354 struct evconnlistener_event
*lev_e
=
355 EVUTIL_UPCAST(lev
, struct evconnlistener_event
, base
);
356 return event_get_base(&lev_e
->listener
);
360 evconnlistener_set_cb(struct evconnlistener
*lev
,
361 evconnlistener_cb cb
, void *arg
)
365 if (lev
->enabled
&& !lev
->cb
)
368 lev
->user_data
= arg
;
370 evconnlistener_enable(lev
);
375 evconnlistener_set_error_cb(struct evconnlistener
*lev
,
376 evconnlistener_errorcb errorcb
)
379 lev
->errorcb
= errorcb
;
384 listener_read_cb(evutil_socket_t fd
, short what
, void *p
)
386 struct evconnlistener
*lev
= p
;
388 evconnlistener_cb cb
;
389 evconnlistener_errorcb errorcb
;
393 struct sockaddr_storage ss
;
395 int socklen
= sizeof(ss
);
397 socklen_t socklen
= sizeof(ss
);
399 evutil_socket_t new_fd
= accept(fd
, (struct sockaddr
*)&ss
, &socklen
);
403 /* This can happen with some older linux kernels in
404 * response to nmap. */
405 evutil_closesocket(new_fd
);
409 if (!(lev
->flags
& LEV_OPT_LEAVE_SOCKETS_BLOCKING
))
410 evutil_make_socket_nonblocking(new_fd
);
412 if (lev
->cb
== NULL
) {
413 evutil_closesocket(new_fd
);
419 user_data
= lev
->user_data
;
421 cb(lev
, new_fd
, (struct sockaddr
*)&ss
, (int)socklen
,
424 if (lev
->refcnt
== 1) {
425 int freed
= listener_decref_and_unlock(lev
);
426 EVUTIL_ASSERT(freed
);
431 err
= evutil_socket_geterror(fd
);
432 if (EVUTIL_ERR_ACCEPT_RETRIABLE(err
)) {
436 if (lev
->errorcb
!= NULL
) {
438 errorcb
= lev
->errorcb
;
439 user_data
= lev
->user_data
;
441 errorcb(lev
, user_data
);
443 listener_decref_and_unlock(lev
);
445 event_sock_warn(fd
, "Error from accept() call");
450 struct accepting_socket
{
451 CRITICAL_SECTION lock
;
452 struct event_overlapped overlapped
;
455 struct deferred_cb deferred
;
456 struct evconnlistener_iocp
*lev
;
459 unsigned free_on_cb
:1;
463 static void accepted_socket_cb(struct event_overlapped
*o
, ev_uintptr_t key
,
464 ev_ssize_t n
, int ok
);
465 static void accepted_socket_invoke_user_cb(struct deferred_cb
*cb
, void *arg
);
468 iocp_listener_event_add(struct evconnlistener_iocp
*lev
)
470 if (lev
->event_added
)
473 lev
->event_added
= 1;
474 event_base_add_virtual(lev
->event_base
);
478 iocp_listener_event_del(struct evconnlistener_iocp
*lev
)
480 if (!lev
->event_added
)
483 lev
->event_added
= 0;
484 event_base_del_virtual(lev
->event_base
);
487 static struct accepting_socket
*
488 new_accepting_socket(struct evconnlistener_iocp
*lev
, int family
)
490 struct accepting_socket
*res
;
494 if (family
== AF_INET
)
495 addrlen
= sizeof(struct sockaddr_in
);
496 else if (family
== AF_INET6
)
497 addrlen
= sizeof(struct sockaddr_in6
);
500 buflen
= (addrlen
+16)*2;
502 res
= mm_calloc(1,sizeof(struct accepting_socket
)-1+buflen
);
506 event_overlapped_init(&res
->overlapped
, accepted_socket_cb
);
507 res
->s
= INVALID_SOCKET
;
509 res
->buflen
= buflen
;
510 res
->family
= family
;
512 event_deferred_cb_init(&res
->deferred
,
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(
581 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
587 stop_accepting(struct accepting_socket
*as
)
591 as
->s
= INVALID_SOCKET
;
596 accepted_socket_invoke_user_cb(struct deferred_cb
*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(
673 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
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(
698 event_base_get_deferred_cb_queue(as
->lev
->event_base
),
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. */