0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsCopyright (C) 2000, 2001, 2004, 2016 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsThis Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsLicense, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrewsfile, You can obtain one at http://mozilla.org/MPL/2.0/.
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David Lawrence
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews$Id: dispatch,v 1.6 2004/03/05 05:04:46 marka Exp $
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffUDP receive:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * General flow:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If I/O result == CANCELED, free the buffer and notify everyone as
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * the various queues drain.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If I/O is error (not canceled and not success) log it, free the buffer,
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * and restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If query:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * if no listeners: free the buffer, restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * if listener: allocate event, fill in details.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If cannot allocate, free buffer, restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * if rq event queue is not empty, queue. else, send.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If response:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Allocate event, fill in details.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If cannot allocate, free buffer, restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * find target. If not found, free buffer, restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * if event queue is not empty, queue. else, send.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * restart.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffUDP restart:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If too many recv()'s are already running, just return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If noone is attached to us, just return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Allocate a new buffer to receive into.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If no more buffers:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If there are buffers handed out: wait for one to come back.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If there are no buffers handed out:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If there are responses attached to us, just return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If there are queries only, send one an error event.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * start recv() on socket. If this fails:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free buffer.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Set dispatch state to "shutting down" and why to "socket error"
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Start failsafe shutdown.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffAdding a response:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If shutting down, return error.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Allocate an unique messageid and return it. If none can be allocated,
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * return that.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Allocate a new structure and fill it in. If no memory, return that.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Insert into the correct linked list.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the receiver is not running, try to start it.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffAdding a request:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If shutting down, return error.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Allocate new structure and fill it in. If no memory, return that.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Insert it into the linked list.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the incoming query packet queue is not empty, pull an item off and
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * send that event to this task.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the receiver is not running, try to start it.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffDetaching a response:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * decrement dispatch reference count by one. If zero, remember to kill it
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * later.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * unlink the response from the hashed list.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free any buffers and events attached to the response structure.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free the response structure.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If an event is also being returned, jump to "internal event free" below.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the ref count became zero above, destroy this dispatch fully, and return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the receiver is not running, try to start it.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffDetaching a request:
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * decrement dispatch ref count by one. If zero, remember to kill it later.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * unlink from the request list.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free the response structure.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If an event is also being returned, jump to "internal event free" below.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the ref count became zero above, destroy the dispatch fully, and return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the receiver is not running, try to start it.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffInternal event free (from library space):
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If it is the failsafe event, send it to the next response/request on the
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * dispatcher, and return.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free buffer.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free event.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael GraffReturning an event (from application space):
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff/*
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If it is the failsafe event, die.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free associated buffer.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * Free event.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If response: do next response on this response's queue, if any.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If request: do next request on this dispatcher's queue, if any.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff *
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff * If the receiver is not running, try to start it.
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff */
b75dc2a3d82c0ad078b5155057e66e5b694faeb7Michael Graff