3 Network input dispatcher... */
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
36 static char copyright
[] =
37 "$Id: dispatch.c,v 1.3 2005/08/11 17:13:21 drochner Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
42 struct timeout
*timeouts
;
43 static struct timeout
*free_timeouts
;
45 void set_time (u_int32_t t
)
47 /* Do any outstanding timeouts. */
50 process_outstanding_timeouts ((struct timeval
*)0);
54 struct timeval
*process_outstanding_timeouts (struct timeval
*tvp
)
56 /* Call any expired timeouts, and then if there's
57 still a timeout registered, time out the select
62 if (timeouts
-> when
<= cur_time
) {
64 timeouts
= timeouts
-> next
;
65 (*(t
-> func
)) (t
-> what
);
67 (*t
-> unref
) (&t
-> what
, MDL
);
68 t
-> next
= free_timeouts
;
73 tvp
-> tv_sec
= timeouts
-> when
;
78 return (struct timeval
*)0;
81 /* Wait for packets to come in using select(). When one does, call
82 receive_packet to receive the packet and possibly strip hardware
83 addressing information from it, and then call through the
84 bootp_packet_handler hook to try to do something with it. */
88 struct timeval tv
, *tvp
;
91 /* Wait for a packet or a timeout... XXX */
93 tvp
= process_outstanding_timeouts (&tv
);
94 status
= omapi_one_dispatch (0, tvp
);
95 } while (status
== ISC_R_TIMEDOUT
|| status
== ISC_R_SUCCESS
);
96 log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
97 isc_result_totext (status
));
100 void add_timeout (when
, where
, what
, ref
, unref
)
102 void (*where
) PROTO ((void *));
107 struct timeout
*t
, *q
;
109 /* See if this timeout supersedes an existing timeout. */
110 t
= (struct timeout
*)0;
111 for (q
= timeouts
; q
; q
= q
-> next
) {
112 if ((where
== NULL
|| q
-> func
== where
) &&
115 t
-> next
= q
-> next
;
117 timeouts
= q
-> next
;
123 /* If we didn't supersede a timeout, allocate a timeout
128 free_timeouts
= q
-> next
;
130 q
= ((struct timeout
*)
131 dmalloc (sizeof (struct timeout
), MDL
));
133 log_fatal ("add_timeout: no memory!");
135 memset (q
, 0, sizeof *q
);
140 (*q
-> ref
)(&q
-> what
, what
, MDL
);
147 /* Now sort this timeout into the timeout list. */
149 /* Beginning of list? */
150 if (!timeouts
|| timeouts
-> when
> q
-> when
) {
151 q
-> next
= timeouts
;
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
;
167 q
-> next
= (struct timeout
*)0;
170 void cancel_timeout (where
, what
)
171 void (*where
) PROTO ((void *));
174 struct timeout
*t
, *q
;
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
) {
179 if (q
-> func
== where
&& q
-> what
== what
) {
181 t
-> next
= q
-> next
;
183 timeouts
= q
-> next
;
189 /* If we found the timeout, put it on the free list. */
192 (*q
-> unref
) (&q
-> what
, MDL
);
193 q
-> next
= free_timeouts
;
198 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
199 void cancel_all_timeouts ()
201 struct timeout
*t
, *n
;
202 for (t
= timeouts
; t
; t
= n
) {
204 if (t
-> unref
&& t
-> what
)
205 (*t
-> unref
) (&t
-> what
, MDL
);
206 t
-> next
= free_timeouts
;
211 void relinquish_timeouts ()
213 struct timeout
*t
, *n
;
214 for (t
= free_timeouts
; t
; t
= n
) {