Annotation of embedaddon/dhcp/common/dispatch.c, revision 1.1
1.1 ! misho 1: /* dispatch.c
! 2:
! 3: Network input dispatcher... */
! 4:
! 5: /*
! 6: * Copyright (c) 2004-2009,2011 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 1995-2003 by Internet Software Consortium
! 8: *
! 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.
! 12: *
! 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.
! 20: *
! 21: * Internet Systems Consortium, Inc.
! 22: * 950 Charter Street
! 23: * Redwood City, CA 94063
! 24: * <info@isc.org>
! 25: * https://www.isc.org/
! 26: *
! 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: * ``https://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''.
! 33: */
! 34:
! 35: #include "dhcpd.h"
! 36:
! 37: struct timeout *timeouts;
! 38: static struct timeout *free_timeouts;
! 39:
! 40: void set_time(TIME t)
! 41: {
! 42: /* Do any outstanding timeouts. */
! 43: if (cur_tv . tv_sec != t) {
! 44: cur_tv . tv_sec = t;
! 45: cur_tv . tv_usec = 0;
! 46: process_outstanding_timeouts ((struct timeval *)0);
! 47: }
! 48: }
! 49:
! 50: struct timeval *process_outstanding_timeouts (struct timeval *tvp)
! 51: {
! 52: /* Call any expired timeouts, and then if there's
! 53: still a timeout registered, time out the select
! 54: call then. */
! 55: another:
! 56: if (timeouts) {
! 57: struct timeout *t;
! 58: if ((timeouts -> when . tv_sec < cur_tv . tv_sec) ||
! 59: ((timeouts -> when . tv_sec == cur_tv . tv_sec) &&
! 60: (timeouts -> when . tv_usec <= cur_tv . tv_usec))) {
! 61: t = timeouts;
! 62: timeouts = timeouts -> next;
! 63: (*(t -> func)) (t -> what);
! 64: if (t -> unref)
! 65: (*t -> unref) (&t -> what, MDL);
! 66: t -> next = free_timeouts;
! 67: free_timeouts = t;
! 68: goto another;
! 69: }
! 70: if (tvp) {
! 71: tvp -> tv_sec = timeouts -> when . tv_sec;
! 72: tvp -> tv_usec = timeouts -> when . tv_usec;
! 73: }
! 74: return tvp;
! 75: } else
! 76: return (struct timeval *)0;
! 77: }
! 78:
! 79: /* Wait for packets to come in using select(). When one does, call
! 80: receive_packet to receive the packet and possibly strip hardware
! 81: addressing information from it, and then call through the
! 82: bootp_packet_handler hook to try to do something with it. */
! 83:
! 84: void dispatch ()
! 85: {
! 86: struct timeval tv, *tvp;
! 87: isc_result_t status;
! 88:
! 89: /* Wait for a packet or a timeout... XXX */
! 90: do {
! 91: tvp = process_outstanding_timeouts (&tv);
! 92: status = omapi_one_dispatch (0, tvp);
! 93: } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
! 94: log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
! 95: isc_result_totext (status));
! 96: }
! 97:
! 98: void add_timeout (when, where, what, ref, unref)
! 99: struct timeval *when;
! 100: void (*where) (void *);
! 101: void *what;
! 102: tvref_t ref;
! 103: tvunref_t unref;
! 104: {
! 105: struct timeout *t, *q;
! 106:
! 107: /* See if this timeout supersedes an existing timeout. */
! 108: t = (struct timeout *)0;
! 109: for (q = timeouts; q; q = q -> next) {
! 110: if ((where == NULL || q -> func == where) &&
! 111: q -> what == what) {
! 112: if (t)
! 113: t -> next = q -> next;
! 114: else
! 115: timeouts = q -> next;
! 116: break;
! 117: }
! 118: t = q;
! 119: }
! 120:
! 121: /* If we didn't supersede a timeout, allocate a timeout
! 122: structure now. */
! 123: if (!q) {
! 124: if (free_timeouts) {
! 125: q = free_timeouts;
! 126: free_timeouts = q -> next;
! 127: } else {
! 128: q = ((struct timeout *)
! 129: dmalloc (sizeof (struct timeout), MDL));
! 130: if (!q)
! 131: log_fatal ("add_timeout: no memory!");
! 132: }
! 133: memset (q, 0, sizeof *q);
! 134: q -> func = where;
! 135: q -> ref = ref;
! 136: q -> unref = unref;
! 137: if (q -> ref)
! 138: (*q -> ref)(&q -> what, what, MDL);
! 139: else
! 140: q -> what = what;
! 141: }
! 142:
! 143: q -> when . tv_sec = when -> tv_sec;
! 144: q -> when . tv_usec = when -> tv_usec;
! 145:
! 146: /* Now sort this timeout into the timeout list. */
! 147:
! 148: /* Beginning of list? */
! 149: if (!timeouts || (timeouts -> when . tv_sec > q -> when . tv_sec) ||
! 150: ((timeouts -> when . tv_sec == q -> when . tv_sec) &&
! 151: (timeouts -> when . tv_usec > q -> when . tv_usec))) {
! 152: q -> next = timeouts;
! 153: timeouts = q;
! 154: return;
! 155: }
! 156:
! 157: /* Middle of list? */
! 158: for (t = timeouts; t -> next; t = t -> next) {
! 159: if ((t -> next -> when . tv_sec > q -> when . tv_sec) ||
! 160: ((t -> next -> when . tv_sec == q -> when . tv_sec) &&
! 161: (t -> next -> when . tv_usec > q -> when . tv_usec))) {
! 162: q -> next = t -> next;
! 163: t -> next = q;
! 164: return;
! 165: }
! 166: }
! 167:
! 168: /* End of list. */
! 169: t -> next = q;
! 170: q -> next = (struct timeout *)0;
! 171: }
! 172:
! 173: void cancel_timeout (where, what)
! 174: void (*where) (void *);
! 175: void *what;
! 176: {
! 177: struct timeout *t, *q;
! 178:
! 179: /* Look for this timeout on the list, and unlink it if we find it. */
! 180: t = (struct timeout *)0;
! 181: for (q = timeouts; q; q = q -> next) {
! 182: if (q -> func == where && q -> what == what) {
! 183: if (t)
! 184: t -> next = q -> next;
! 185: else
! 186: timeouts = q -> next;
! 187: break;
! 188: }
! 189: t = q;
! 190: }
! 191:
! 192: /* If we found the timeout, put it on the free list. */
! 193: if (q) {
! 194: if (q -> unref)
! 195: (*q -> unref) (&q -> what, MDL);
! 196: q -> next = free_timeouts;
! 197: free_timeouts = q;
! 198: }
! 199: }
! 200:
! 201: #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 202: void cancel_all_timeouts ()
! 203: {
! 204: struct timeout *t, *n;
! 205: for (t = timeouts; t; t = n) {
! 206: n = t -> next;
! 207: if (t -> unref && t -> what)
! 208: (*t -> unref) (&t -> what, MDL);
! 209: t -> next = free_timeouts;
! 210: free_timeouts = t;
! 211: }
! 212: }
! 213:
! 214: void relinquish_timeouts ()
! 215: {
! 216: struct timeout *t, *n;
! 217: for (t = free_timeouts; t; t = n) {
! 218: n = t -> next;
! 219: dfree (t, MDL);
! 220: }
! 221: }
! 222: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>