1*5411bbb6Srenato /* $OpenBSD: accept.c,v 1.7 2016/05/23 19:11:42 renato Exp $ */
24dda87d0Sclaudio
34dda87d0Sclaudio /*
44dda87d0Sclaudio * Copyright (c) 2012 Claudio Jeker <claudio@openbsd.org>
54dda87d0Sclaudio *
64dda87d0Sclaudio * Permission to use, copy, modify, and distribute this software for any
74dda87d0Sclaudio * purpose with or without fee is hereby granted, provided that the above
84dda87d0Sclaudio * copyright notice and this permission notice appear in all copies.
94dda87d0Sclaudio *
104dda87d0Sclaudio * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
114dda87d0Sclaudio * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
124dda87d0Sclaudio * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
134dda87d0Sclaudio * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
144dda87d0Sclaudio * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
154dda87d0Sclaudio * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
164dda87d0Sclaudio * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
174dda87d0Sclaudio */
184dda87d0Sclaudio
19*5411bbb6Srenato #include <sys/types.h>
204dda87d0Sclaudio #include <stdlib.h>
214dda87d0Sclaudio
224dda87d0Sclaudio #include "ldpd.h"
234dda87d0Sclaudio #include "ldpe.h"
244dda87d0Sclaudio #include "log.h"
254dda87d0Sclaudio
264dda87d0Sclaudio struct accept_ev {
274dda87d0Sclaudio LIST_ENTRY(accept_ev) entry;
284dda87d0Sclaudio struct event ev;
294dda87d0Sclaudio void (*accept_cb)(int, short, void *);
304dda87d0Sclaudio void *arg;
314dda87d0Sclaudio int fd;
324dda87d0Sclaudio };
334dda87d0Sclaudio
344dda87d0Sclaudio struct {
354dda87d0Sclaudio LIST_HEAD(, accept_ev) queue;
364dda87d0Sclaudio struct event evt;
374dda87d0Sclaudio } accept_queue;
384dda87d0Sclaudio
39c28a25a1Srenato static void accept_arm(void);
40c28a25a1Srenato static void accept_unarm(void);
41c28a25a1Srenato static void accept_cb(int, short, void *);
42c28a25a1Srenato static void accept_timeout(int, short, void *);
434dda87d0Sclaudio
444dda87d0Sclaudio void
accept_init(void)454dda87d0Sclaudio accept_init(void)
464dda87d0Sclaudio {
474dda87d0Sclaudio LIST_INIT(&accept_queue.queue);
484dda87d0Sclaudio evtimer_set(&accept_queue.evt, accept_timeout, NULL);
494dda87d0Sclaudio }
504dda87d0Sclaudio
514dda87d0Sclaudio int
accept_add(int fd,void (* cb)(int,short,void *),void * arg)524dda87d0Sclaudio accept_add(int fd, void (*cb)(int, short, void *), void *arg)
534dda87d0Sclaudio {
544dda87d0Sclaudio struct accept_ev *av;
554dda87d0Sclaudio
564dda87d0Sclaudio if ((av = calloc(1, sizeof(*av))) == NULL)
5771256830Srenato return (-1);
584dda87d0Sclaudio av->fd = fd;
594dda87d0Sclaudio av->accept_cb = cb;
604dda87d0Sclaudio av->arg = arg;
614dda87d0Sclaudio LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
624dda87d0Sclaudio
634dda87d0Sclaudio event_set(&av->ev, av->fd, EV_READ, accept_cb, av);
644dda87d0Sclaudio event_add(&av->ev, NULL);
654dda87d0Sclaudio
66b7b4db73Srenato log_debug("%s: accepting on fd %d", __func__, fd);
674dda87d0Sclaudio
684dda87d0Sclaudio return (0);
694dda87d0Sclaudio }
704dda87d0Sclaudio
714dda87d0Sclaudio void
accept_del(int fd)724dda87d0Sclaudio accept_del(int fd)
734dda87d0Sclaudio {
744dda87d0Sclaudio struct accept_ev *av;
754dda87d0Sclaudio
764dda87d0Sclaudio LIST_FOREACH(av, &accept_queue.queue, entry)
774dda87d0Sclaudio if (av->fd == fd) {
78b7b4db73Srenato log_debug("%s: %d removed from queue", __func__, fd);
794dda87d0Sclaudio event_del(&av->ev);
804dda87d0Sclaudio LIST_REMOVE(av, entry);
814dda87d0Sclaudio free(av);
824dda87d0Sclaudio return;
834dda87d0Sclaudio }
844dda87d0Sclaudio }
854dda87d0Sclaudio
864dda87d0Sclaudio void
accept_pause(void)874dda87d0Sclaudio accept_pause(void)
884dda87d0Sclaudio {
894dda87d0Sclaudio struct timeval evtpause = { 1, 0 };
904dda87d0Sclaudio
91b7b4db73Srenato log_debug(__func__);
924dda87d0Sclaudio accept_unarm();
934dda87d0Sclaudio evtimer_add(&accept_queue.evt, &evtpause);
944dda87d0Sclaudio }
954dda87d0Sclaudio
964dda87d0Sclaudio void
accept_unpause(void)974dda87d0Sclaudio accept_unpause(void)
984dda87d0Sclaudio {
994dda87d0Sclaudio if (evtimer_pending(&accept_queue.evt, NULL)) {
100b7b4db73Srenato log_debug(__func__);
1014dda87d0Sclaudio evtimer_del(&accept_queue.evt);
1024dda87d0Sclaudio accept_arm();
1034dda87d0Sclaudio }
1044dda87d0Sclaudio }
1054dda87d0Sclaudio
106c28a25a1Srenato static void
accept_arm(void)1074dda87d0Sclaudio accept_arm(void)
1084dda87d0Sclaudio {
1094dda87d0Sclaudio struct accept_ev *av;
1104dda87d0Sclaudio LIST_FOREACH(av, &accept_queue.queue, entry)
1114dda87d0Sclaudio event_add(&av->ev, NULL);
1124dda87d0Sclaudio }
1134dda87d0Sclaudio
114c28a25a1Srenato static void
accept_unarm(void)1154dda87d0Sclaudio accept_unarm(void)
1164dda87d0Sclaudio {
1174dda87d0Sclaudio struct accept_ev *av;
1184dda87d0Sclaudio LIST_FOREACH(av, &accept_queue.queue, entry)
1194dda87d0Sclaudio event_del(&av->ev);
1204dda87d0Sclaudio }
1214dda87d0Sclaudio
122c28a25a1Srenato static void
accept_cb(int fd,short event,void * arg)1234dda87d0Sclaudio accept_cb(int fd, short event, void *arg)
1244dda87d0Sclaudio {
1254dda87d0Sclaudio struct accept_ev *av = arg;
1264dda87d0Sclaudio event_add(&av->ev, NULL);
1274dda87d0Sclaudio av->accept_cb(fd, event, av->arg);
1284dda87d0Sclaudio }
1294dda87d0Sclaudio
130c28a25a1Srenato static void
accept_timeout(int fd,short event,void * bula)1314dda87d0Sclaudio accept_timeout(int fd, short event, void *bula)
1324dda87d0Sclaudio {
133b7b4db73Srenato log_debug(__func__);
1344dda87d0Sclaudio accept_arm();
1354dda87d0Sclaudio }
136