/** Report connection classes to a client. * @param[in] sptr Client requesting statistics. * @param[in] sd Stats descriptor for request (ignored). * @param[in] param Extra parameter from user (ignored). */ void report_classes(struct Client *sptr, const struct StatDesc *sd, char *param) { struct ConnectionClass *cltmp; for (cltmp = connClassList; cltmp; cltmp = cltmp->next) send_reply(sptr, RPL_STATSYLINE, (cltmp->valid ? 'Y' : 'y'), ConClass(cltmp), PingFreq(cltmp), ConFreq(cltmp), MaxLinks(cltmp), MaxSendq(cltmp), Links(cltmp) - 1); }
struct Class * make_class(void) { struct Class *tmp; tmp = rb_malloc(sizeof(struct Class)); ConFreq(tmp) = DEFAULT_CONNECTFREQUENCY; PingFreq(tmp) = DEFAULT_PINGFREQUENCY; MaxUsers(tmp) = 1; MaxSendq(tmp) = DEFAULT_SENDQ; tmp->ip_limits = rb_new_patricia(PATRICIA_BITS); return tmp; }
/** Initialize the connection class list. * A connection class named "default" is created, with ping frequency, * connection frequency, maximum links and max SendQ values from the * corresponding configuration features. */ void init_class(void) { if (!connClassList) { connClassList = (struct ConnectionClass*) make_class(); connClassList->next = 0; } /* We had better not try and free this... */ ConClass(connClassList) = "default"; PingFreq(connClassList) = feature_int(FEAT_PINGFREQUENCY); ConFreq(connClassList) = feature_int(FEAT_CONNECTFREQUENCY); MaxLinks(connClassList) = feature_int(FEAT_MAXIMUM_LINKS); MaxSendq(connClassList) = feature_uint(FEAT_DEFAULTMAXSENDQLENGTH); connClassList->valid = 1; Links(connClassList) = 1; }
/** Make sure we have a connection class named \a name. * If one does not exist, create it. Then set its ping frequency, * connection frequency, maximum link count, and max SendQ according * to the parameters. * @param[in] name Connection class name. * @param[in] ping Ping frequency for clients in this class. * @param[in] confreq Connection frequency for clients. * @param[in] maxli Maximum link count for class. * @param[in] sendq Max SendQ for clients. */ void add_class(char *name, unsigned int ping, unsigned int confreq, unsigned int maxli, unsigned int sendq) { struct ConnectionClass* p; Debug((DEBUG_DEBUG, "Add Class %s: cf: %u pf: %u ml: %u sq: %d", name, confreq, ping, maxli, sendq)); assert(name != NULL); p = do_find_class(name, 1); if (!p) p = make_class(); else MyFree(ConClass(p)); ConClass(p) = name; ConFreq(p) = confreq; PingFreq(p) = ping; MaxLinks(p) = maxli; MaxSendq(p) = (sendq > 0U) ? sendq : feature_uint(FEAT_DEFAULTMAXSENDQLENGTH); p->valid = 1; }
/** Unlink (and dereference) invalid connection classes. * This is used in combination with class_mark_delete() during rehash * to get rid of connection classes that are no longer in the * configuration. */ void class_delete_marked(void) { struct ConnectionClass* cl; struct ConnectionClass* prev; Debug((DEBUG_DEBUG, "Class check:")); for (prev = cl = connClassList; cl; cl = prev->next) { Debug((DEBUG_DEBUG, "Class %s : CF: %d PF: %d ML: %d LI: %d SQ: %d", ConClass(cl), ConFreq(cl), PingFreq(cl), MaxLinks(cl), Links(cl), MaxSendq(cl))); /* * unlink marked classes, delete unreferenced ones */ if (cl->valid || Links(cl) > 1) prev = cl; else { prev->next = cl->next; free_class(cl); } } }
/** Return maximum SendQ length for a client. * @param[in] cptr Local client to check. * @return Number of bytes allowed in SendQ for \a cptr. */ unsigned int get_sendq(struct Client *cptr) { assert(0 != cptr); assert(0 != cli_local(cptr)); if (cli_max_sendq(cptr)) return cli_max_sendq(cptr); else if (cli_confs(cptr)) { struct SLink* tmp; struct ConnectionClass* cl; for (tmp = cli_confs(cptr); tmp; tmp = tmp->next) { if (!tmp->value.aconf || !(cl = tmp->value.aconf->conn_class)) continue; if (ConClass(cl) != NULL) { cli_max_sendq(cptr) = MaxSendq(cl); return cli_max_sendq(cptr); } } } return feature_uint(FEAT_DEFAULTMAXSENDQLENGTH); }