dispatch revision 9bff67898d55cddfcec9ce30cc2b1bb6211ec691
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David LawrenceCopyright (C) 2000 Internet Software Consortium.
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David LawrenceSee COPYRIGHT in the source root or http://www.isc.org/copyright for terms.
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David 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