1 /******************************************************************************/
2 /* postlicyd: a postfix policy daemon with a lot of features */
4 /* ________________________________________________________________________ */
6 /* Redistribution and use in source and binary forms, with or without */
7 /* modification, are permitted provided that the following conditions */
10 /* 1. Redistributions of source code must retain the above copyright */
11 /* notice, this list of conditions and the following disclaimer. */
12 /* 2. Redistributions in binary form must reproduce the above copyright */
13 /* notice, this list of conditions and the following disclaimer in the */
14 /* documentation and/or other materials provided with the distribution. */
15 /* 3. The names of its contributors may not be used to endorse or promote */
16 /* products derived from this software without specific prior written */
19 /* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */
21 /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
22 /* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS */
23 /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
24 /* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */
25 /* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */
26 /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */
27 /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */
28 /* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF */
29 /* THE POSSIBILITY OF SUCH DAMAGE. */
30 /******************************************************************************/
33 * Copyright © 2007 Pierre Habouzit
44 #define GAI_SIGNO (SIGRTMIN+0)
56 static int gai_fifo_end(void)
58 int res = fifo.start + fifo.len;
59 return res >= fifo.size ? res - fifo.size : fifo.size;
62 static void gai_fifo_append(gai_req *rq)
64 if (fifo.len >= fifo.size) {
65 p_realloc(&fifo.ring, fifo.size += 16);
68 fifo.ring[gai_fifo_end()] = rq;
72 static gai_req *gai_fifo_pop(void)
76 while (!res && fifo.len) {
77 res = fifo.ring[fifo.start];
78 fifo.start++, fifo.len--;
79 if (fifo.start >= fifo.size)
86 static void gai_fifo_remove(gai_req *rq)
88 int i, end = gai_fifo_end();
90 if (fifo.start + fifo.len <= fifo.size) {
91 for (i = fifo.start; i < end; i++) {
92 if (fifo.ring[i] == rq)
96 for (i = fifo.start; i < fifo.size; i++) {
97 if (fifo.ring[i] == rq)
100 for (i = 0; i < end; i++) {
101 if (fifo.ring[i] == rq)
107 static gai_req *gai_req_new(void)
109 gai_req *rq = p_new(gai_req, 1);
113 static void gai_req_delete(gai_req **rqp)
118 switch (gai_error(rq->cbp)) {
120 if (gai_cancel(rq->cbp) == EAI_NOTCANCELED) {
130 default: /* we are likely in the notify list remove us ! */
136 p_delete((char **)&rq->cb.ar_name);
137 freeaddrinfo(rq->cb.ar_result);
138 rq->cb.ar_result = NULL;
143 gai_req *gai_query(job_t *caller, const char *lookup)
145 struct sigevent se = {
146 .sigev_signo = GAI_SIGNO,
147 .sigev_notify = SIGEV_SIGNAL,
151 se.sigev_value.sival_ptr = res = gai_req_new();
152 res->cb.ar_name = strdup(lookup);
153 res->caller = caller;
154 getaddrinfo_a(GAI_NOWAIT, &res->cbp, 1, &se);
159 void gai_abort(gai_req **rqp)
165 static void gai_sigaction(int sig, siginfo_t *si, void *ctx)
167 gai_req *req = si->_sifields._rt.si_sigval.sival_ptr;
169 assert (sig == GAI_SIGNO);
170 assert (req && gai_error(req->cbp) != EAI_INPROGRESS);
173 gai_fifo_append(req);
175 gai_req_delete(&req);
179 void gai_initialize(void)
181 struct sigaction sa = {
182 .sa_sigaction = &gai_sigaction,
183 .sa_flags = SA_SIGINFO,
185 if (sigaction(GAI_SIGNO, &sa, NULL) < 0) {
186 syslog(LOG_ERR, "cannot hook SIGRTMIN+0: %m");
191 void gai_process(void)
195 while ((req = gai_fifo_pop())) {
196 assert (req->caller && req->caller->process);
197 req->caller->process(req->caller);
198 req->caller = NULL; /* make delete faster: avoid gai_fifo_remove() */
202 void gai_shutdown(void)
204 /* TODO: deallocate the fifo properly */