Annotation of embedaddon/dhcp/common/dispatch.c, revision 1.1.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>