/** 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 (con_dns_reply(con)) --(con_dns_reply(con)->ref_count); if (con_dnsbl_reply(con)) --(con_dnsbl_reply(con)->ref_count); 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)); if (con_loc(con)) MyFree(con_loc(con)); --connections.inuse; con_next(con) = connectionFreeList; connectionFreeList = con; con_magic(con) = 0; }
/* * Create a new struct Client structure and set it to initial state. * * from == NULL, create local client (a client connected to a socket). * * from != NULL, create remote client (behind a socket associated with * the client defined by 'from'). * ('from' is a local client!!). */ struct Client* make_client(struct Client *from, int status) { struct Client* cptr = 0; struct Connection* con = 0; assert(!from || cli_verify(from)); cptr = alloc_client(); assert(0 != cptr); assert(!cli_magic(cptr)); assert(0 == from || 0 != cli_connect(from)); if (!from) { /* local client, allocate a struct Connection */ con = alloc_connection(); assert(0 != con); assert(!con_magic(con)); con_magic(con) = CONNECTION_MAGIC; con_fd(con) = -1; /* initialize struct Connection */ con_freeflag(con) = 0; con_nextnick(con) = CurrentTime - NICK_DELAY; con_nexttarget(con) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1)); con_handler(con) = UNREGISTERED_HANDLER; con_client(con) = cptr; cli_local(cptr) = 1; /* Set certain fields of the struct Client */ cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime; cli_lastnick(cptr) = TStime(); } else con = cli_connect(from); /* use 'from's connection */ assert(0 != con); assert(con_verify(con)); cli_magic(cptr) = CLIENT_MAGIC; cli_connect(cptr) = con; /* set the connection and other fields */ cli_status(cptr) = status; cli_hnext(cptr) = cptr; strcpy(cli_username(cptr), "unknown"); return cptr; }