From c1b01bf5ec318463ab076ac2d7c0a4b02631f745 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sun, 3 Sep 2023 23:19:00 +0000 Subject: [PATCH] client: refactor del_all_accepts to allow skipping own accept list This allows reusing this function for other uses that just need to remove this client from others' accept lists on nick change and not have duplicates of this code everywhere --- include/client.h | 2 +- ircd/client.c | 16 ++++++++++++---- ircd/s_user.c | 2 +- modules/core/m_nick.c | 17 +---------------- modules/m_services.c | 5 ++++- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/include/client.h b/include/client.h index 2d61d5f9..bf7ca79b 100644 --- a/include/client.h +++ b/include/client.h @@ -603,7 +603,7 @@ extern struct Client *find_named_person(const char *); extern struct Client *next_client(struct Client *, const char *); #define accept_message(s, t) ((s) == (t) || (rb_dlinkFind((s), &((t)->localClient->allow_list)))) -extern void del_all_accepts(struct Client *client_p); +extern void del_all_accepts(struct Client *client_p, bool self_too); extern void dead_link(struct Client *client_p, int sendqex); extern int show_ip(struct Client *source_p, struct Client *target_p); diff --git a/ircd/client.c b/ircd/client.c index a06fda58..9482b37c 100644 --- a/ircd/client.c +++ b/ircd/client.c @@ -1385,7 +1385,7 @@ exit_generic_client(struct Client *client_p, struct Client *source_p, struct Cli } /* Clean up allow lists */ - del_all_accepts(source_p); + del_all_accepts(source_p, true); whowas_add_history(source_p, 0); whowas_off_history(source_p); @@ -1793,19 +1793,19 @@ count_remote_client_memory(size_t * count, size_t * remote_client_memory_used) /* * del_all_accepts * - * inputs - pointer to exiting client + * inputs - pointer to exiting client, flag to include own allow_list * output - NONE * side effects - Walk through given clients allow_list and on_allow_list * remove all references to this client */ void -del_all_accepts(struct Client *client_p) +del_all_accepts(struct Client *client_p, bool self_too) { rb_dlink_node *ptr; rb_dlink_node *next_ptr; struct Client *target_p; - if(MyClient(client_p) && client_p->localClient->allow_list.head) + if(self_too && MyClient(client_p) && client_p->localClient->allow_list.head) { /* clear this clients accept list, and remove them from * everyones on_accept_list @@ -1813,6 +1813,7 @@ del_all_accepts(struct Client *client_p) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->allow_list.head) { target_p = ptr->data; + rb_dlinkFindDestroy(client_p, &target_p->on_allow_list); rb_dlinkDestroy(ptr, &client_p->localClient->allow_list); } @@ -1822,6 +1823,13 @@ del_all_accepts(struct Client *client_p) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head) { target_p = ptr->data; + + /* If we're not doing our own, we're doing this because of a nick change. + * Skip those that would see the nick change anyway + */ + if(!self_too && has_common_channel(client_p, target_p)) + continue; + rb_dlinkFindDestroy(client_p, &target_p->localClient->allow_list); rb_dlinkDestroy(ptr, &client_p->on_allow_list); } diff --git a/ircd/s_user.c b/ircd/s_user.c index 48acff5b..94fee03c 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -1725,7 +1725,7 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use if(changed) { monitor_signon(target_p); - del_all_accepts(target_p); + del_all_accepts(target_p, false); } } diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c index 890d0c2b..dcdd4837 100644 --- a/modules/core/m_nick.c +++ b/modules/core/m_nick.c @@ -619,8 +619,6 @@ static void change_local_nick(struct Client *client_p, struct Client *source_p, char *nick, int dosend) { - struct Client *target_p; - rb_dlink_node *ptr, *next_ptr; struct Channel *chptr; char note[NICKLEN + 10]; int samenick; @@ -704,20 +702,7 @@ change_local_nick(struct Client *client_p, struct Client *source_p, /* Make sure everyone that has this client on its accept list * loses that reference. */ - /* we used to call del_all_accepts() here, but theres no real reason - * to clear a clients own list of accepted clients. So just remove - * them from everyone elses list --anfl - */ - RB_DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->on_allow_list.head) - { - target_p = ptr->data; - - if (!has_common_channel(source_p, target_p)) - { - rb_dlinkFindDestroy(source_p, &target_p->localClient->allow_list); - rb_dlinkDestroy(ptr, &source_p->on_allow_list); - } - } + del_all_accepts(source_p, false); snprintf(note, sizeof(note), "Nick: %s", nick); rb_note(client_p->localClient->F, note); diff --git a/modules/m_services.c b/modules/m_services.c index 0127887e..bf378600 100644 --- a/modules/m_services.c +++ b/modules/m_services.c @@ -280,7 +280,10 @@ doit: monitor_signon(target_p); - del_all_accepts(target_p); + /* Make sure everyone that has this client on its accept list + * loses that reference. + */ + del_all_accepts(target_p, false); snprintf(note, sizeof(note), "Nick: %s", target_p->name); rb_note(target_p->localClient->F, note);