]> git.ipfire.org Git - thirdparty/dhcp.git/blame - common/dispatch.c
Merge changes between 3.0rc7 and 3.0rc8pl2.
[thirdparty/dhcp.git] / common / dispatch.c
CommitLineData
48d507a9 1/* dispatch.c
decf33c2 2
48d507a9 3 Network input dispatcher... */
decf33c2
TL
4
5/*
eb6b5a20 6 * Copyright (c) 1995-2001 Internet Software Consortium.
49733f31 7 * All rights reserved.
decf33c2 8 *
49733f31
TL
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
decf33c2 12 *
49733f31
TL
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 Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
decf33c2 21 *
49733f31
TL
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
decf33c2
TL
42 */
43
44#ifndef lint
45static char copyright[] =
d758ad8c 46"$Id: dispatch.c,v 1.64 2001/06/27 00:29:45 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n";
decf33c2
TL
47#endif /* not lint */
48
49#include "dhcpd.h"
decf33c2 50
6806c5ae
TL
51struct timeout *timeouts;
52static struct timeout *free_timeouts;
decf33c2 53
eb6b5a20
TL
54void set_time (u_int32_t t)
55{
56 /* Do any outstanding timeouts. */
57 if (cur_time != t) {
58 cur_time = t;
59 process_outstanding_timeouts ((struct timeval *)0);
60 }
61}
62
63struct timeval *process_outstanding_timeouts (struct timeval *tvp)
64{
65 /* Call any expired timeouts, and then if there's
66 still a timeout registered, time out the select
67 call then. */
68 another:
69 if (timeouts) {
70 struct timeout *t;
71 if (timeouts -> when <= cur_time) {
72 t = timeouts;
73 timeouts = timeouts -> next;
74 (*(t -> func)) (t -> what);
75 if (t -> unref)
76 (*t -> unref) (&t -> what, MDL);
77 t -> next = free_timeouts;
78 free_timeouts = t;
79 goto another;
80 }
81 if (tvp) {
82 tvp -> tv_sec = timeouts -> when;
83 tvp -> tv_usec = 0;
84 }
85 return tvp;
86 } else
87 return (struct timeval *)0;
88}
89
decf33c2
TL
90/* Wait for packets to come in using select(). When one does, call
91 receive_packet to receive the packet and possibly strip hardware
b25cbbad
TL
92 addressing information from it, and then call through the
93 bootp_packet_handler hook to try to do something with it. */
decf33c2 94
e4749e75 95void dispatch ()
decf33c2 96{
6806c5ae 97 struct timeval tv, *tvp;
16be3937 98 isc_result_t status;
decf33c2 99
eb6b5a20 100 /* Wait for a packet or a timeout... XXX */
decf33c2 101 do {
eb6b5a20 102 tvp = process_outstanding_timeouts (&tv);
16be3937
TL
103 status = omapi_one_dispatch (0, tvp);
104 } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
eac1e66f 105 log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
00763cc1 106 isc_result_totext (status));
decf33c2
TL
107}
108
20916cae 109void add_timeout (when, where, what, ref, unref)
6806c5ae 110 TIME when;
e4749e75
TL
111 void (*where) PROTO ((void *));
112 void *what;
20916cae
TL
113 tvref_t ref;
114 tvunref_t unref;
6806c5ae
TL
115{
116 struct timeout *t, *q;
117
118 /* See if this timeout supersedes an existing timeout. */
119 t = (struct timeout *)0;
120 for (q = timeouts; q; q = q -> next) {
bdcaf7b9
TL
121 if ((where == NULL || q -> func == where) &&
122 q -> what == what) {
6806c5ae
TL
123 if (t)
124 t -> next = q -> next;
125 else
126 timeouts = q -> next;
127 break;
128 }
129 t = q;
130 }
131
132 /* If we didn't supersede a timeout, allocate a timeout
133 structure now. */
134 if (!q) {
135 if (free_timeouts) {
136 q = free_timeouts;
137 free_timeouts = q -> next;
6806c5ae 138 } else {
4bd8800e
TL
139 q = ((struct timeout *)
140 dmalloc (sizeof (struct timeout), MDL));
6806c5ae 141 if (!q)
16be3937 142 log_fatal ("add_timeout: no memory!");
6806c5ae 143 }
20916cae
TL
144 memset (q, 0, sizeof *q);
145 q -> func = where;
146 q -> ref = ref;
147 q -> unref = unref;
148 if (q -> ref)
149 (*q -> ref)(&q -> what, what, MDL);
150 else
151 q -> what = what;
6806c5ae
TL
152 }
153
154 q -> when = when;
155
156 /* Now sort this timeout into the timeout list. */
157
158 /* Beginning of list? */
159 if (!timeouts || timeouts -> when > q -> when) {
160 q -> next = timeouts;
161 timeouts = q;
162 return;
163 }
164
165 /* Middle of list? */
166 for (t = timeouts; t -> next; t = t -> next) {
167 if (t -> next -> when > q -> when) {
168 q -> next = t -> next;
169 t -> next = q;
170 return;
171 }
172 }
173
174 /* End of list. */
175 t -> next = q;
176 q -> next = (struct timeout *)0;
177}
178
179void cancel_timeout (where, what)
e4749e75
TL
180 void (*where) PROTO ((void *));
181 void *what;
6806c5ae
TL
182{
183 struct timeout *t, *q;
184
185 /* Look for this timeout on the list, and unlink it if we find it. */
186 t = (struct timeout *)0;
187 for (q = timeouts; q; q = q -> next) {
e4749e75 188 if (q -> func == where && q -> what == what) {
6806c5ae
TL
189 if (t)
190 t -> next = q -> next;
191 else
192 timeouts = q -> next;
193 break;
194 }
195 t = q;
196 }
197
198 /* If we found the timeout, put it on the free list. */
199 if (q) {
20916cae
TL
200 if (q -> unref)
201 (*q -> unref) (&q -> what, MDL);
6806c5ae
TL
202 q -> next = free_timeouts;
203 free_timeouts = q;
204 }
205}
d758ad8c
TL
206
207#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
208void cancel_all_timeouts ()
209{
210 struct timeout *t, *n;
211 for (t = timeouts; t; t = n) {
212 n = t -> next;
213 if (t -> unref && t -> what)
214 (*t -> unref) (&t -> what, MDL);
215 t -> next = free_timeouts;
216 free_timeouts = t;
217 }
218}
219
220void relinquish_timeouts ()
221{
222 struct timeout *t, *n;
223 for (t = free_timeouts; t; t = n) {
224 n = t -> next;
225 dfree (t, MDL);
226 }
227}
228#endif