+/** Allocate a new Client structure.
+ * If #clientFreeList != NULL, use the head of that list.
+ * Otherwise, allocate a new structure.
+ * @return Newly allocated Client.
+ */
+static struct Client* alloc_client(void)
+{
+ struct Client* cptr = clientFreeList;
+
+ if (!cptr) {
+ cptr = (struct Client*) MyMalloc(sizeof(struct Client));
+ clients.alloc++;
+ } else
+ clientFreeList = cli_next(cptr);
+
+ clients.inuse++;
+
+ memset(cptr, 0, sizeof(struct Client));
+
+ return cptr;
+}
+
+/** Release a Client structure by prepending it to #clientFreeList.
+ * @param[in] cptr Client that is no longer being used.
+ */
+static void dealloc_client(struct Client* cptr)
+{
+ assert(cli_verify(cptr));
+ assert(0 == cli_connect(cptr));
+
+ --clients.inuse;
+
+ cli_next(cptr) = clientFreeList;
+ clientFreeList = cptr;
+
+ cli_magic(cptr) = 0;
+}
+
+/** Allocate a new Connection structure.
+ * If #connectionFreeList != NULL, use the head of that list.
+ * Otherwise, allocate a new structure.
+ * @return Newly allocated Connection.
+ */
+static struct Connection* alloc_connection(void)
+{
+ struct Connection* con = connectionFreeList;
+
+ if (!con) {
+ con = (struct Connection*) MyMalloc(sizeof(struct Connection));
+ connections.alloc++;
+ } else
+ connectionFreeList = con_next(con);
+
+ connections.inuse++;
+
+ memset(con, 0, sizeof(struct Connection));
+ timer_init(&(con_proc(con)));
+
+ return con;
+}
+
+/** Release a Connection and all memory associated with it.
+ * The connection's DNS reply field is freed, its file descriptor is
+ * closed, its msgq and sendq are cleared, and its associated Listener
+ * is dereferenced. Then it is prepended to #connectionFreeList.
+ * @param[in] con Connection to free.
+ */
+static void dealloc_connection(struct Connection* con)
+{
+ assert(con_verify(con));
+ assert(!t_active(&(con_proc(con))));
+ assert(!t_onqueue(&(con_proc(con))));
+
+ Debug((DEBUG_LIST, "Deallocating connection %p", con));
+
+ if (-1 < con_fd(con))
+ close(con_fd(con));
+ MsgQClear(&(con_sendQ(con)));
+ client_drop_sendq(con);
+ DBufClear(&(con_recvQ(con)));
+ if (con_listener(con))
+ release_listener(con_listener(con));
+
+ --connections.inuse;
+
+ con_next(con) = connectionFreeList;
+ connectionFreeList = con;
+
+ con_magic(con) = 0;
+}
+
+/** Allocate a new client and initialize it.
+ * If \a from == NULL, initialize the fields for a local client,
+ * including allocating a Connection for him; otherwise initialize the
+ * fields for a remote client..
+ * @param[in] from Server connection that introduced the client (or
+ * NULL).
+ * @param[in] status Initial Client::cli_status value.
+ * @return Newly allocated and initialized Client.