]>
Commit | Line | Data |
---|---|---|
48d507a9 | 1 | /* dispatch.c |
decf33c2 | 2 | |
48d507a9 | 3 | Network input dispatcher... */ |
decf33c2 TL |
4 | |
5 | /* | |
49733f31 TL |
6 | * Copyright (c) 1995-2000 Internet Software Consortium. |
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 | |
45 | static char copyright[] = | |
20916cae | 46 | "$Id: dispatch.c,v 1.62 2000/05/16 23:02:14 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; |
decf33c2 TL |
47 | #endif /* not lint */ |
48 | ||
49 | #include "dhcpd.h" | |
decf33c2 | 50 | |
6806c5ae TL |
51 | struct timeout *timeouts; |
52 | static struct timeout *free_timeouts; | |
decf33c2 | 53 | |
7d77172d | 54 | int interfaces_invalidated; |
decf33c2 TL |
55 | |
56 | /* Wait for packets to come in using select(). When one does, call | |
57 | receive_packet to receive the packet and possibly strip hardware | |
b25cbbad TL |
58 | addressing information from it, and then call through the |
59 | bootp_packet_handler hook to try to do something with it. */ | |
decf33c2 | 60 | |
e4749e75 | 61 | void dispatch () |
decf33c2 | 62 | { |
decf33c2 | 63 | fd_set r, w, x; |
e4749e75 | 64 | struct protocol *l; |
decf33c2 TL |
65 | int max = 0; |
66 | int count; | |
6806c5ae | 67 | struct timeval tv, *tvp; |
16be3937 | 68 | isc_result_t status; |
decf33c2 TL |
69 | |
70 | do { | |
6806c5ae TL |
71 | /* Call any expired timeouts, and then if there's |
72 | still a timeout registered, time out the select | |
73 | call then. */ | |
74 | another: | |
75 | if (timeouts) { | |
76 | struct timeout *t; | |
77 | if (timeouts -> when <= cur_time) { | |
78 | t = timeouts; | |
79 | timeouts = timeouts -> next; | |
e4749e75 | 80 | (*(t -> func)) (t -> what); |
20916cae TL |
81 | if (t -> unref) |
82 | (*t -> unref) (&t -> what, MDL); | |
6806c5ae TL |
83 | t -> next = free_timeouts; |
84 | free_timeouts = t; | |
85 | goto another; | |
86 | } | |
16be3937 | 87 | tv.tv_sec = timeouts -> when; |
6806c5ae TL |
88 | tv.tv_usec = 0; |
89 | tvp = &tv; | |
90 | } else | |
91 | tvp = (struct timeval *)0; | |
92 | ||
decf33c2 | 93 | /* Wait for a packet or a timeout... XXX */ |
16be3937 TL |
94 | status = omapi_one_dispatch (0, tvp); |
95 | } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS); | |
eac1e66f | 96 | log_fatal ("omapi_one_dispatch failed: %s -- exiting.", |
00763cc1 | 97 | isc_result_totext (status)); |
decf33c2 TL |
98 | } |
99 | ||
20916cae | 100 | void add_timeout (when, where, what, ref, unref) |
6806c5ae | 101 | TIME when; |
e4749e75 TL |
102 | void (*where) PROTO ((void *)); |
103 | void *what; | |
20916cae TL |
104 | tvref_t ref; |
105 | tvunref_t unref; | |
6806c5ae TL |
106 | { |
107 | struct timeout *t, *q; | |
108 | ||
109 | /* See if this timeout supersedes an existing timeout. */ | |
110 | t = (struct timeout *)0; | |
111 | for (q = timeouts; q; q = q -> next) { | |
bdcaf7b9 TL |
112 | if ((where == NULL || q -> func == where) && |
113 | q -> what == what) { | |
6806c5ae TL |
114 | if (t) |
115 | t -> next = q -> next; | |
116 | else | |
117 | timeouts = q -> next; | |
118 | break; | |
119 | } | |
120 | t = q; | |
121 | } | |
122 | ||
123 | /* If we didn't supersede a timeout, allocate a timeout | |
124 | structure now. */ | |
125 | if (!q) { | |
126 | if (free_timeouts) { | |
127 | q = free_timeouts; | |
128 | free_timeouts = q -> next; | |
6806c5ae | 129 | } else { |
4bd8800e TL |
130 | q = ((struct timeout *) |
131 | dmalloc (sizeof (struct timeout), MDL)); | |
6806c5ae | 132 | if (!q) |
16be3937 | 133 | log_fatal ("add_timeout: no memory!"); |
6806c5ae | 134 | } |
20916cae TL |
135 | memset (q, 0, sizeof *q); |
136 | q -> func = where; | |
137 | q -> ref = ref; | |
138 | q -> unref = unref; | |
139 | if (q -> ref) | |
140 | (*q -> ref)(&q -> what, what, MDL); | |
141 | else | |
142 | q -> what = what; | |
6806c5ae TL |
143 | } |
144 | ||
145 | q -> when = when; | |
146 | ||
147 | /* Now sort this timeout into the timeout list. */ | |
148 | ||
149 | /* Beginning of list? */ | |
150 | if (!timeouts || timeouts -> when > q -> when) { | |
151 | q -> next = timeouts; | |
152 | timeouts = q; | |
153 | return; | |
154 | } | |
155 | ||
156 | /* Middle of list? */ | |
157 | for (t = timeouts; t -> next; t = t -> next) { | |
158 | if (t -> next -> when > q -> when) { | |
159 | q -> next = t -> next; | |
160 | t -> next = q; | |
161 | return; | |
162 | } | |
163 | } | |
164 | ||
165 | /* End of list. */ | |
166 | t -> next = q; | |
167 | q -> next = (struct timeout *)0; | |
168 | } | |
169 | ||
170 | void cancel_timeout (where, what) | |
e4749e75 TL |
171 | void (*where) PROTO ((void *)); |
172 | void *what; | |
6806c5ae TL |
173 | { |
174 | struct timeout *t, *q; | |
175 | ||
176 | /* Look for this timeout on the list, and unlink it if we find it. */ | |
177 | t = (struct timeout *)0; | |
178 | for (q = timeouts; q; q = q -> next) { | |
e4749e75 | 179 | if (q -> func == where && q -> what == what) { |
6806c5ae TL |
180 | if (t) |
181 | t -> next = q -> next; | |
182 | else | |
183 | timeouts = q -> next; | |
184 | break; | |
185 | } | |
186 | t = q; | |
187 | } | |
188 | ||
189 | /* If we found the timeout, put it on the free list. */ | |
190 | if (q) { | |
20916cae TL |
191 | if (q -> unref) |
192 | (*q -> unref) (&q -> what, MDL); | |
6806c5ae TL |
193 | q -> next = free_timeouts; |
194 | free_timeouts = q; | |
195 | } | |
196 | } |