]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/accept.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / ldpd / accept.c
1 /* $OpenBSD$ */
2
3 /*
4 * Copyright (c) 2012 Claudio Jeker <claudio@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <zebra.h>
20
21 #include "ldpd.h"
22 #include "ldpe.h"
23 #include "log.h"
24
25 struct accept_ev {
26 LIST_ENTRY(accept_ev) entry;
27 struct thread *ev;
28 void (*accept_cb)(struct thread *);
29 void *arg;
30 int fd;
31 };
32
33 struct {
34 LIST_HEAD(, accept_ev) queue;
35 struct thread *evt;
36 } accept_queue;
37
38 static void accept_arm(void);
39 static void accept_unarm(void);
40 static void accept_cb(struct thread *);
41 static void accept_timeout(struct thread *);
42
43 void
44 accept_init(void)
45 {
46 LIST_INIT(&accept_queue.queue);
47 }
48
49 int accept_add(int fd, void (*cb)(struct thread *), void *arg)
50 {
51 struct accept_ev *av;
52
53 if ((av = calloc(1, sizeof(*av))) == NULL)
54 return (-1);
55 av->fd = fd;
56 av->accept_cb = cb;
57 av->arg = arg;
58 LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
59
60 thread_add_read(master, accept_cb, av, av->fd, &av->ev);
61
62 log_debug("%s: accepting on fd %d", __func__, fd);
63
64 return (0);
65 }
66
67 void
68 accept_del(int fd)
69 {
70 struct accept_ev *av;
71
72 LIST_FOREACH(av, &accept_queue.queue, entry)
73 if (av->fd == fd) {
74 log_debug("%s: %d removed from queue", __func__, fd);
75 THREAD_OFF(av->ev);
76 LIST_REMOVE(av, entry);
77 free(av);
78 return;
79 }
80 }
81
82 void
83 accept_pause(void)
84 {
85 log_debug(__func__);
86 accept_unarm();
87 thread_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt);
88 }
89
90 void
91 accept_unpause(void)
92 {
93 if (accept_queue.evt != NULL) {
94 log_debug(__func__);
95 THREAD_OFF(accept_queue.evt);
96 accept_arm();
97 }
98 }
99
100 static void
101 accept_arm(void)
102 {
103 struct accept_ev *av;
104 LIST_FOREACH(av, &accept_queue.queue, entry) {
105 thread_add_read(master, accept_cb, av, av->fd, &av->ev);
106 }
107 }
108
109 static void
110 accept_unarm(void)
111 {
112 struct accept_ev *av;
113 LIST_FOREACH(av, &accept_queue.queue, entry)
114 THREAD_OFF(av->ev);
115 }
116
117 static void accept_cb(struct thread *thread)
118 {
119 struct accept_ev *av = THREAD_ARG(thread);
120 thread_add_read(master, accept_cb, av, av->fd, &av->ev);
121 av->accept_cb(thread);
122 }
123
124 static void accept_timeout(struct thread *thread)
125 {
126 accept_queue.evt = NULL;
127
128 log_debug(__func__);
129 accept_arm();
130 }