From 994544c294af3bcab070124dfab4967b775435ca Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 23 Nov 2007 22:11:25 +0100 Subject: [PATCH] Merge links_cache into scache and rework scache. This changes flattened /links output to disclose less routing information and slightly increases memory "leak" from server names that do not come back anymore. --- doc/reference.conf | 4 +- include/cache.h | 4 -- include/client.h | 2 + include/s_conf.h | 1 - include/scache.h | 8 ++- modules/core/m_server.c | 5 ++ modules/m_gline.c | 4 +- modules/m_links.c | 29 +--------- src/cache.c | 39 -------------- src/client.c | 3 ++ src/ircd.c | 7 +-- src/newconf.c | 8 --- src/s_serv.c | 1 + src/scache.c | 114 +++++++++++++++++++++++++++++++++------- src/whowas.c | 2 +- 15 files changed, 122 insertions(+), 109 deletions(-) diff --git a/doc/reference.conf b/doc/reference.conf index e0277583..a532fb06 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -664,8 +664,8 @@ serverhide { */ flatten_links = no; - /* links delay: how often to update the links file when it is - * flattened. + /* links delay: how long to wait before showing splits or new + * servers in a flattened /links output. */ links_delay = 5 minutes; diff --git a/include/cache.h b/include/cache.h index a3485ecc..f60b5b9a 100644 --- a/include/cache.h +++ b/include/cache.h @@ -9,8 +9,6 @@ #define CACHELINELEN 81 #define CACHEFILELEN 30 -/* two servernames, a gecos, three spaces, ":1", '\0' */ -#define LINKSLINELEN (HOSTLEN + HOSTLEN + REALLEN + 6) #define HELP_USER 0x001 #define HELP_OPER 0x002 @@ -33,13 +31,11 @@ struct cacheline extern struct cachefile *user_motd; extern struct cachefile *oper_motd; extern struct cacheline *emptyline; -extern dlink_list links_cache_list; extern char user_motd_changed[MAX_DATE_STRING]; extern void init_cache(void); extern struct cachefile *cache_file(const char *, const char *, int); -extern void cache_links(void *unused); extern void free_cachefile(struct cachefile *); extern void load_help(void); diff --git a/include/client.h b/include/client.h index 3065c21f..0b6adccb 100644 --- a/include/client.h +++ b/include/client.h @@ -69,6 +69,7 @@ struct LocalUser; struct AuthRequest; struct PreClient; struct ListClient; +struct scache_entry; /* * Atheme's coding standards require that we use BSD-style user-defined types @@ -107,6 +108,7 @@ struct Server dlink_list users; int caps; /* capabilities bit-field */ char *fullcaps; + struct scache_entry *nameinfo; }; struct SlinkRpl diff --git a/include/s_conf.h b/include/s_conf.h index 846d2fe2..2b69e6a1 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -276,7 +276,6 @@ struct config_server_hide { int flatten_links; int links_delay; - int links_disabled; int hidden; int disable_hidden; }; diff --git a/include/scache.h b/include/scache.h index 9c7fc277..ffbffb59 100644 --- a/include/scache.h +++ b/include/scache.h @@ -27,8 +27,14 @@ #ifndef INCLUDED_scache_h #define INCLUDED_scache_h +struct Client; +struct scache_entry; + extern void clear_scache_hash_table(void); -extern const char *find_or_add(const char *name); +extern struct scache_entry *scache_connect(const char *name, const char *info, int hidden); +extern void scache_split(struct scache_entry *ptr); +extern const char *scache_get_name(struct scache_entry *ptr); +extern void scache_send_flattened_links(struct Client *source_p); extern void count_scache(size_t *, size_t *); #endif diff --git a/modules/core/m_server.c b/modules/core/m_server.c index 408fd06f..8ccfeb3e 100644 --- a/modules/core/m_server.c +++ b/modules/core/m_server.c @@ -38,6 +38,7 @@ #include "s_log.h" /* log level defines */ #include "s_serv.h" /* server_estab, check_server */ #include "s_stats.h" /* ServerStats */ +#include "scache.h" #include "send.h" /* sendto_one */ #include "msg.h" #include "parse.h" @@ -426,6 +427,8 @@ ms_server(struct Client *client_p, struct Client *source_p, int parc, const char add_to_client_hash(target_p->name, target_p); dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->servers); + target_p->serv->nameinfo = scache_connect(target_p->name, target_p->info, IsHidden(target_p)); + sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s SERVER %s %d :%s%s", source_p->name, target_p->name, target_p->hopcount + 1, @@ -573,6 +576,8 @@ ms_sid(struct Client *client_p, struct Client *source_p, int parc, const char *p add_to_id_hash(target_p->id, target_p); dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->servers); + target_p->serv->nameinfo = scache_connect(target_p->name, target_p->info, IsHidden(target_p)); + sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s SID %s %d %s :%s%s", source_p->id, target_p->name, target_p->hopcount + 1, diff --git a/modules/m_gline.c b/modules/m_gline.c index 92d87d2e..1d9ecb82 100644 --- a/modules/m_gline.c +++ b/modules/m_gline.c @@ -651,7 +651,7 @@ majority_gline(struct Client *source_p, const char *user, strlcpy(pending->oper_host2, source_p->host, sizeof(pending->oper_host2)); DupString(pending->reason2, reason); - pending->oper_server2 = find_or_add(source_p->servptr->name); + pending->oper_server2 = scache_get_name(source_p->servptr->serv->nameinfo); pending->last_gline_time = CurrentTime; pending->time_request2 = CurrentTime; return NO; @@ -670,7 +670,7 @@ majority_gline(struct Client *source_p, const char *user, strlcpy(pending->oper_host1, source_p->host, sizeof(pending->oper_host1)); - pending->oper_server1 = find_or_add(source_p->servptr->name); + pending->oper_server1 = scache_get_name(source_p->servptr->serv->nameinfo); strlcpy(pending->user, user, sizeof(pending->user)); strlcpy(pending->host, host, sizeof(pending->host)); diff --git a/modules/m_links.c b/modules/m_links.c index c7aaeeaa..295baa6b 100644 --- a/modules/m_links.c +++ b/modules/m_links.c @@ -36,7 +36,7 @@ #include "parse.h" #include "modules.h" #include "hook.h" -#include "cache.h" +#include "scache.h" static int m_links(struct Client *, struct Client *, int, const char **); static int mo_links(struct Client *, struct Client *, int, const char **); @@ -56,8 +56,6 @@ mapi_hlist_av1 links_hlist[] = { DECLARE_MODULE_AV1(links, NULL, NULL, links_clist, links_hlist, NULL, "$Revision: 254 $"); -static void send_links_cache(struct Client *source_p); - /* * m_links - LINKS message handler * parv[0] = sender prefix @@ -71,7 +69,7 @@ static int m_links(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { if(ConfigServerHide.flatten_links && !IsExemptShide(source_p)) - send_links_cache(source_p); + scache_send_flattened_links(source_p); else mo_links(client_p, source_p, parc, parv); @@ -131,26 +129,3 @@ mo_links(struct Client *client_p, struct Client *source_p, int parc, const char return 0; } -/* send_links_cache() - * - * inputs - client to send to - * outputs - the cached links, us, and RPL_ENDOFLINKS - * side effects - - */ -static void -send_links_cache(struct Client *source_p) -{ - dlink_node *ptr; - - DLINK_FOREACH(ptr, links_cache_list.head) - { - sendto_one(source_p, ":%s 364 %s %s", - me.name, source_p->name, (const char *)ptr->data); - } - - sendto_one_numeric(source_p, RPL_LINKS, form_str(RPL_LINKS), - me.name, me.name, 0, me.info); - - sendto_one_numeric(source_p, RPL_ENDOFLINKS, form_str(RPL_ENDOFLINKS), "*"); -} - diff --git a/src/cache.c b/src/cache.c index 0a23ebbc..c55364a7 100644 --- a/src/cache.c +++ b/src/cache.c @@ -50,7 +50,6 @@ static BlockHeap *cacheline_heap = NULL; struct cachefile *user_motd = NULL; struct cachefile *oper_motd = NULL; -dlink_list links_cache_list; char user_motd_changed[MAX_DATE_STRING]; /* init_cache() @@ -69,7 +68,6 @@ init_cache(void) user_motd = cache_file(MPATH, "ircd.motd", 0); oper_motd = cache_file(OPATH, "opers.motd", 0); - memset(&links_cache_list, 0, sizeof(links_cache_list)); } /* cache_file() @@ -131,43 +129,6 @@ cache_file(const char *filename, const char *shortname, int flags) return cacheptr; } -void -cache_links(void *unused) -{ - struct Client *target_p; - dlink_node *ptr; - dlink_node *next_ptr; - char *links_line; - - DLINK_FOREACH_SAFE(ptr, next_ptr, links_cache_list.head) - { - MyFree(ptr->data); - free_dlink_node(ptr); - } - - links_cache_list.head = links_cache_list.tail = NULL; - links_cache_list.length = 0; - - DLINK_FOREACH(ptr, global_serv_list.head) - { - target_p = ptr->data; - - /* skip ourselves (done in /links) and hidden servers */ - if(IsMe(target_p) || - (IsHidden(target_p) && !ConfigServerHide.disable_hidden)) - continue; - - /* if the below is ever modified, change LINKSLINELEN */ - links_line = MyMalloc(LINKSLINELEN); - ircsnprintf(links_line, LINKSLINELEN, "%s %s :1 %s", - target_p->name, me.name, - target_p->info[0] ? target_p->info : - "(Unknown Location)"); - - dlinkAddTailAlloc(links_line, &links_cache_list); - } -} - /* free_cachefile() * * inputs - cachefile to free diff --git a/src/client.c b/src/client.c index bdebefcc..bb0f472f 100644 --- a/src/client.c +++ b/src/client.c @@ -59,6 +59,7 @@ #include "monitor.h" #include "blacklist.h" #include "reject.h" +#include "scache.h" #define DEBUG_EXITED_CLIENTS @@ -1487,6 +1488,7 @@ exit_remote_server(struct Client *client_p, struct Client *source_p, struct Clie del_from_client_hash(source_p->name, source_p); remove_client_from_list(source_p); + scache_split(source_p->serv->nameinfo); SetDead(source_p); #ifdef DEBUG_EXITED_CLIENTS @@ -1583,6 +1585,7 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien del_from_client_hash(source_p->name, source_p); remove_client_from_list(source_p); + scache_split(source_p->serv->nameinfo); SetDead(source_p); dlinkAddAlloc(source_p, &dead_list); diff --git a/src/ircd.c b/src/ircd.c index 75e689e3..a134e915 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -638,6 +638,7 @@ main(int argc, char *argv[]) startup_time = CurrentTime; add_to_client_hash(me.name, &me); add_to_id_hash(me.id, &me); + me.serv->nameinfo = scache_connect(me.name, me.info, 0); dlinkAddAlloc(&me, &global_serv_list); @@ -667,12 +668,6 @@ main(int argc, char *argv[]) eventAdd("check_rehash", check_rehash, NULL, 1); - if(ConfigServerHide.links_delay > 0) - eventAdd("cache_links", cache_links, NULL, - ConfigServerHide.links_delay); - else - ConfigServerHide.links_disabled = 1; - if(splitmode) eventAdd("check_splitmode", check_splitmode, NULL, 2); diff --git a/src/newconf.c b/src/newconf.c index 8c1e52b5..4f642055 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -1528,14 +1528,6 @@ conf_set_serverhide_links_delay(void *data) { int val = *(unsigned int *) data; - if((val > 0) && ConfigServerHide.links_disabled == 1) - { - eventAddIsh("cache_links", cache_links, NULL, val); - ConfigServerHide.links_disabled = 0; - } - else if(val != ConfigServerHide.links_delay) - eventUpdate("cache_links", val); - ConfigServerHide.links_delay = val; } diff --git a/src/s_serv.c b/src/s_serv.c index 582d154b..df8dfe4a 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -1117,6 +1117,7 @@ server_estab(struct Client *client_p) client_p->localClient->fullcaps = NULL; } + client_p->serv->nameinfo = scache_connect(client_p->name, client_p->info, IsHidden(client_p)); client_p->localClient->firsttime = CurrentTime; /* fixing eob timings.. -gnp */ diff --git a/src/scache.c b/src/scache.c index 0819bbd4..c5a7d13f 100644 --- a/src/scache.c +++ b/src/scache.c @@ -33,6 +33,7 @@ #include "send.h" #include "scache.h" #include "memory.h" +#include "s_conf.h" /* @@ -42,19 +43,29 @@ * in its lifetime is at most a few hundred. by tokenizing server * names internally, the server can easily save 2 or 3 megs of RAM. * -orabidoo + * + * reworked to serve for flattening/delaying /links also + * -- jilles */ #define SCACHE_HASH_SIZE 257 -typedef struct scache_entry +#define SC_ONLINE 1 +#define SC_HIDDEN 2 + +struct scache_entry { char name[HOSTLEN + 1]; + char info[REALLEN + 1]; + int flags; + time_t known_since; + time_t last_connect; + time_t last_split; struct scache_entry *next; -} -SCACHE; +}; -static SCACHE *scache_hash[SCACHE_HASH_SIZE]; +static struct scache_entry *scache_hash[SCACHE_HASH_SIZE]; void clear_scache_hash_table(void) @@ -76,37 +87,104 @@ sc_hash(const char *string) return hash_value % SCACHE_HASH_SIZE; } -/* - * this takes a server name, and returns a pointer to the same string - * (up to case) in the server name token list, adding it to the list if - * it's not there. care must be taken not to call this with - * user-supplied arguments that haven't been verified to be a valid, - * existing, servername. use the hash in list.c for those. -orabidoo - */ - -const char * +static struct scache_entry * find_or_add(const char *name) { int hash_index; - SCACHE *ptr; + struct scache_entry *ptr; ptr = scache_hash[hash_index = sc_hash(name)]; for (; ptr; ptr = ptr->next) { if(!irccmp(ptr->name, name)) - return (ptr->name); + return ptr; } - ptr = (SCACHE *) MyMalloc(sizeof(SCACHE)); + ptr = (struct scache_entry *) MyMalloc(sizeof(struct scache_entry)); s_assert(0 != ptr); strlcpy(ptr->name, name, sizeof(ptr->name)); + ptr->info[0] = '\0'; + ptr->flags = 0; + ptr->known_since = CurrentTime; + ptr->last_connect = 0; + ptr->last_split = 0; ptr->next = scache_hash[hash_index]; scache_hash[hash_index] = ptr; + return ptr; +} + +struct scache_entry * +scache_connect(const char *name, const char *info, int hidden) +{ + struct scache_entry *ptr; + + ptr = find_or_add(name); + strlcpy(ptr->info, info, sizeof(ptr->info)); + ptr->flags |= SC_ONLINE; + if (hidden) + ptr->flags |= SC_HIDDEN; + else + ptr->flags &= ~SC_HIDDEN; + ptr->last_connect = CurrentTime; + return ptr; +} + +void +scache_split(struct scache_entry *ptr) +{ + if (ptr == NULL) + return; + ptr->flags &= ~SC_ONLINE; + ptr->last_split = CurrentTime; +} + +const char *scache_get_name(struct scache_entry *ptr) +{ return ptr->name; } +/* scache_send_flattened_links() + * + * inputs - client to send to + * outputs - the cached links, us, and RPL_ENDOFLINKS + * side effects - + */ +void +scache_send_flattened_links(struct Client *source_p) +{ + struct scache_entry *scache_ptr; + int i; + int show; + + for (i = 0; i < SCACHE_HASH_SIZE; i++) + { + scache_ptr = scache_hash[i]; + while (scache_ptr) + { + if (!irccmp(scache_ptr->name, me.name)) + show = FALSE; + else if (scache_ptr->flags & SC_HIDDEN && + !ConfigServerHide.disable_hidden) + show = FALSE; + else if (scache_ptr->flags & SC_ONLINE) + show = scache_ptr->known_since < CurrentTime - ConfigServerHide.links_delay; + else + show = scache_ptr->last_split > CurrentTime - ConfigServerHide.links_delay && scache_ptr->last_split - scache_ptr->known_since > ConfigServerHide.links_delay; + if (show) + sendto_one_numeric(source_p, RPL_LINKS, form_str(RPL_LINKS), + scache_ptr->name, me.name, 1, scache_ptr->info); + + scache_ptr = scache_ptr->next; + } + } + sendto_one_numeric(source_p, RPL_LINKS, form_str(RPL_LINKS), + me.name, me.name, 0, me.info); + + sendto_one_numeric(source_p, RPL_ENDOFLINKS, form_str(RPL_ENDOFLINKS), "*"); +} + /* * count_scache * inputs - pointer to where to leave number of servers cached @@ -117,7 +195,7 @@ find_or_add(const char *name) void count_scache(size_t * number_servers_cached, size_t * mem_servers_cached) { - SCACHE *scache_ptr; + struct scache_entry *scache_ptr; int i; *number_servers_cached = 0; @@ -130,7 +208,7 @@ count_scache(size_t * number_servers_cached, size_t * mem_servers_cached) { *number_servers_cached = *number_servers_cached + 1; *mem_servers_cached = *mem_servers_cached + - (strlen(scache_ptr->name) + sizeof(SCACHE *)); + sizeof(struct scache_entry ); scache_ptr = scache_ptr->next; } diff --git a/src/whowas.c b/src/whowas.c index d72cea15..880826fc 100644 --- a/src/whowas.c +++ b/src/whowas.c @@ -87,7 +87,7 @@ void add_history(struct Client *client_p, int online) else who->sockhost[0] = '\0'; - who->servername = find_or_add(client_p->servptr->name); + who->servername = scache_get_name(client_p->servptr->serv->nameinfo); if(online) {