/** Release a Client. * In addition to the cleanup done by dealloc_client(), this will free * any pending auth request, free the connection for local clients, * and delete the processing timer for the client. * @param[in] cptr Client to free. */ void free_client(struct Client* cptr) { if (!cptr) return; /* * forget to remove the client from the hash table? */ assert(cli_verify(cptr)); assert(cli_hnext(cptr) == cptr); /* or from linked list? */ assert(cli_next(cptr) == 0); assert(cli_prev(cptr) == 0); Debug((DEBUG_LIST, "Freeing client %s [%p], connection %p", cli_name(cptr), cptr, cli_connect(cptr))); if (cli_auth(cptr)) destroy_auth_request(cli_auth(cptr), 0); /* Make sure we didn't magically get re-added to the list */ assert(cli_next(cptr) == 0); assert(cli_prev(cptr) == 0); if (cli_from(cptr) == cptr) { /* in other words, we're local */ cli_from(cptr) = 0; /* timer must be marked as not active */ if (!cli_freeflag(cptr) && !t_active(&(cli_proc(cptr)))) dealloc_connection(cli_connect(cptr)); /* connection not open anymore */ else { if (-1 < cli_fd(cptr) && cli_freeflag(cptr) & FREEFLAG_SOCKET) socket_del(&(cli_socket(cptr))); /* queue a socket delete */ if (cli_freeflag(cptr) & FREEFLAG_TIMER) timer_del(&(cli_proc(cptr))); /* queue a timer delete */ } } cli_connect(cptr) = 0; dealloc_client(cptr); /* actually destroy the client */ }
/* * auth_timeout - timeout a given auth request */ static void auth_timeout_callback(struct Event* ev) { struct AuthRequest* auth; assert(0 != ev_timer(ev)); assert(0 != t_data(ev_timer(ev))); auth = t_data(ev_timer(ev)); if (ev_type(ev) == ET_DESTROY) { /* being destroyed */ auth->flags &= ~AM_TIMEOUT; if (!(auth->flags & AM_FREE_MASK)) { Debug((DEBUG_LIST, "Freeing auth from timeout callback; %p [%p]", auth, ev_timer(ev))); MyFree(auth); /* done with it, finally */ } } else { assert(ev_type(ev) == ET_EXPIRE); destroy_auth_request(auth, 1); } }