source: rtems-libbsd/ipsec-tools/src/racoon/schedule.c @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*      $NetBSD: schedule.c,v 1.7 2009/01/23 09:10:13 tteras Exp $      */
2
3/*      $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $       */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Copyright (C) 2008 Timo Teras.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the project nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include "config.h"
36
37#include <sys/types.h>
38#include <sys/param.h>
39#include <sys/time.h>
40#include <sys/queue.h>
41#include <sys/socket.h>
42
43#include <stdlib.h>
44#include <unistd.h>
45#include <stdio.h>
46#include <string.h>
47#include <errno.h>
48#include <time.h>
49
50#include "misc.h"
51#include "plog.h"
52#include "schedule.h"
53#include "var.h"
54#include "gcmalloc.h"
55
56#ifndef TAILQ_FOREACH
57#define TAILQ_FOREACH(elm, head, field) \
58        for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field))
59#endif
60
61static TAILQ_HEAD(_schedtree, sched) sctree;
62
63void
64sched_get_monotonic_time(tv)
65        struct timeval *tv;
66{
67#ifdef HAVE_CLOCK_MONOTONIC
68        struct timespec ts;
69
70        clock_gettime(CLOCK_MONOTONIC, &ts);
71        tv->tv_sec = ts.tv_sec;
72        tv->tv_usec = ts.tv_nsec / 1000;
73#else
74        gettimeofday(tv, NULL);
75#endif
76}
77
78time_t
79sched_monotonic_to_time_t(tv, now)
80        struct timeval *tv, *now;
81{
82#ifdef HAVE_CLOCK_MONOTONIC
83        struct timeval mynow, res;
84
85        if (now == NULL) {
86                sched_get_monotonic_time(&mynow);
87                now = &mynow;
88        }
89        timersub(now, tv, &res);
90
91        return time(NULL) + res.tv_sec;
92#else
93        return tv->tv_sec;
94#endif
95}
96
97/*
98 * schedule handler
99 * OUT:
100 *      time to block until next event.
101 *      if no entry, NULL returned.
102 */
103struct timeval *
104schedular()
105{
106        static struct timeval timeout;
107        struct timeval now;
108        struct sched *p;
109
110        sched_get_monotonic_time(&now);
111        while (!TAILQ_EMPTY(&sctree) &&
112                timercmp(&TAILQ_FIRST(&sctree)->xtime, &now, <=)) {
113                void (*func)(struct sched *);
114
115                p = TAILQ_FIRST(&sctree);
116                func = p->func;
117                sched_cancel(p);
118                func(p);
119        }
120
121        p = TAILQ_FIRST(&sctree);
122        if (p == NULL)
123                return NULL;
124
125        timersub(&p->xtime, &now, &timeout);
126
127        return &timeout;
128}
129
130/*
131 * add new schedule to schedule table.
132 */
133void
134sched_schedule(sc, tick, func)
135        struct sched *sc;
136        time_t tick;
137        void (*func) __P((struct sched *));
138{
139        static long id = 1;
140        struct sched *p;
141        struct timeval now;
142
143        sched_cancel(sc);
144
145        sc->func = func;
146        sc->id = id++;
147        sc->tick.tv_sec = tick;
148        sc->tick.tv_usec = 0;
149        sched_get_monotonic_time(&now);
150        timeradd(&now, &sc->tick, &sc->xtime);
151
152        /* add to schedule table */
153        TAILQ_FOREACH(p, &sctree, chain) {
154                if (timercmp(&sc->xtime, &p->xtime, <))
155                        break;
156        }
157        if (p == NULL)
158                TAILQ_INSERT_TAIL(&sctree, sc, chain);
159        else
160                TAILQ_INSERT_BEFORE(p, sc, chain);
161}
162
163/*
164 * cancel scheduled callback
165 */
166void
167sched_cancel(sc)
168        struct sched *sc;
169{
170        if (sc->func != NULL) {
171                TAILQ_REMOVE(&sctree, sc, chain);
172                sc->func = NULL;
173        }
174}
175
176/*
177 * for debug
178 */
179int
180sched_dump(buf, len)
181        caddr_t *buf;
182        int *len;
183{
184        caddr_t new;
185        struct sched *p;
186        struct scheddump *dst;
187        struct timeval now, created;
188        int cnt = 0;
189
190        /* initialize */
191        *len = 0;
192        *buf = NULL;
193
194        TAILQ_FOREACH(p, &sctree, chain)
195                cnt++;
196
197        /* no entry */
198        if (cnt == 0)
199                return -1;
200
201        *len = cnt * sizeof(*dst);
202
203        new = racoon_malloc(*len);
204        if (new == NULL)
205                return -1;
206        dst = (struct scheddump *)new;
207
208        sched_get_monotonic_time(&now);
209        p = TAILQ_FIRST(&sctree);
210        while (p) {
211                timersub(&p->xtime, &p->tick, &created);
212                dst->xtime = p->xtime.tv_sec;
213                dst->id = p->id;
214                dst->created = sched_monotonic_to_time_t(&created, &now);
215                dst->tick = p->tick.tv_sec;
216
217                p = TAILQ_NEXT(p, chain);
218                if (p == NULL)
219                        break;
220                dst++;
221        }
222
223        *buf = new;
224
225        return 0;
226}
227
228/* initialize schedule table */
229void
230sched_init()
231{
232        TAILQ_INIT(&sctree);
233}
234
235#ifdef STEST
236#include <sys/types.h>
237#include <sys/time.h>
238#include <unistd.h>
239#include <err.h>
240
241void
242test(tick)
243        int *tick;
244{
245        printf("execute %d\n", *tick);
246        racoon_free(tick);
247}
248
249void
250getstdin()
251{
252        int *tick;
253        char buf[16];
254
255        read(0, buf, sizeof(buf));
256        if (buf[0] == 'd') {
257                struct scheddump *scbuf, *p;
258                int len;
259                sched_dump((caddr_t *)&scbuf, &len);
260                if (scbuf == NULL)
261                        return;
262                for (p = scbuf; len; p++) {
263                        printf("xtime=%ld\n", p->xtime);
264                        len -= sizeof(*p);
265                }
266                racoon_free(scbuf);
267                return;
268        }
269
270        tick = (int *)racoon_malloc(sizeof(*tick));
271        *tick = atoi(buf);
272        printf("new queue tick = %d\n", *tick);
273        sched_new(*tick, test, tick);
274}
275
276int
277main()
278{
279        static fd_set mask0;
280        int nfds = 0;
281        fd_set rfds;
282        struct timeval *timeout;
283        int error;
284
285        FD_ZERO(&mask0);
286        FD_SET(0, &mask0);
287        nfds = 1;
288
289        /* initialize */
290        sched_init();
291
292        while (1) {
293                rfds = mask0;
294
295                timeout = schedular();
296
297                error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout);
298                if (error < 0) {
299                        switch (errno) {
300                        case EINTR: continue;
301                        default:
302                                err(1, "select");
303                        }
304                        /*NOTREACHED*/
305                }
306
307                if (FD_ISSET(0, &rfds))
308                        getstdin();
309        }
310}
311#endif
Note: See TracBrowser for help on using the repository browser.