0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-03-14 05:20:17 +01:00

ircd: Move tgchange related into namespace.

This commit is contained in:
Jason Volk 2016-08-23 16:55:37 -07:00
parent b85b33d668
commit 3e26e7ab44
11 changed files with 163 additions and 137 deletions

View file

@ -164,7 +164,7 @@ m_displaymsg(struct MsgBuf *msgbuf_p, client::client &source, const char *channe
return;
/* enforce target change on roleplay commands */
if(!is_chanop(msptr) && !is_voiced(msptr) && !is(source, umode::OPER) && !add_channel_target(&source, chptr))
if(!is_chanop(msptr) && !is_voiced(msptr) && !is(source, umode::OPER) && !tgchange::add_target(source, *chptr))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name, source.name, chptr->name.c_str());

View file

@ -79,14 +79,6 @@ enum flags
EXEMPTJUPE = 0x08000000,
};
enum class tgchange
{
NUM = 10, // how many targets we keep track of
REPLY = 5, // how many reply targets
INITIAL = 10, // initial free targets (normal)
INITIAL_LOW = 4, // initial free targets (possible spambot)
};
// we store ipv6 ips for remote clients, so this needs to be v6 always
constexpr auto PASSWDLEN = 128;
constexpr auto CIPHERKEYLEN = 64; // 512bit
@ -267,7 +259,7 @@ struct LocalUser
* 0..TGCHANGE_NUM-1 regular slots
* TGCHANGE_NUM..TGCHANGE_NUM+TGCHANGE_REPLY-1 reply slots
*/
uint32_t targets[int(tgchange::NUM) + int(tgchange::REPLY)];
uint32_t targets[tgchange::NUM + tgchange::REPLY];
unsigned int targets_free; /* free targets */
time_t target_last; /* last time we cleared a slot */

View file

@ -58,16 +58,8 @@ extern void init_s_newconf(void);
extern void clear_s_newconf(void);
extern void clear_s_newconf_bans(void);
typedef struct
{
char *ip;
time_t expiry;
rb_patricia_node_t *pnode;
rb_dlink_node node;
} tgchange;
void add_tgchange(const char *host);
tgchange *find_tgchange(const char *host);
tgchange::tgchange *find_tgchange(const char *host);
/* shared/cluster/hub/leaf confs */
struct remote_conf

View file

@ -77,6 +77,7 @@ namespace ircd
#include "match.h"
#include "tgchange.h"
#include "msgbuf.h"
#include "msg.h"
#include "client.h"
@ -122,7 +123,6 @@ namespace ircd
#include "substitution.h"
#include "supported.h"
#include "s_user.h"
#include "tgchange.h"
#include "whowas.h"
#include "wsproc.h"

View file

@ -4,6 +4,7 @@
* Copyright (C) 2004-2005 Lee Hardy <lee@leeh.co.uk>
* Copyright (C) 2005-2010 Jilles Tjoelker <jilles@stack.nl>
* Copyright (C) 2004-2005 ircd-ratbox development team
* Copyright (C) 2016 Charybdis Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,16 +26,38 @@
#define HAVE_IRCD_TGCHANGE_H
#ifdef __cplusplus
namespace ircd {
namespace ircd {
namespace tgchange {
/* finds a channel where source_p has op or voice and target_p is a member */
chan::chan *find_allowing_channel(client::client *source_p, client::client *target_p);
/* checks if source_p is allowed to send to target_p */
int add_target(client::client *source_p, client::client *target_p);
/* checks if source_p is allowed to send to chptr */
int add_channel_target(client::client *source_p, chan::chan *chptr);
/* allows source_p to send to target_p */
void add_reply_target(client::client *source_p, client::client *target_p);
using client::client;
using chan::chan;
const auto NUM = 10; // how many targets we keep track of
const auto REPLY = 5; // how many reply targets
const auto INITIAL = 10; // initial free targets (normal)
const auto INITIAL_LOW = 4; // initial free targets (possible spambot)
struct tgchange
{
char *ip;
time_t expiry;
rb_patricia_node_t *pnode;
rb_dlink_node node;
};
// finds a channel where source_p has op or voice and target_p is a member
const chan *find_allowing_channel(const client &source, const client &target);
chan *find_allowing_channel(client &source, const client &target);
// allows source_p to send to target_p
void add_reply_target(client &source, const client &target);
// checks if source_p is allowed to send to chptr
bool add_target(client &source, const chan &target);
// checks if source_p is allowed to send to target_p
bool add_target(client &source, const client &target);
} // namespace tgchange
} // namespace ircd
#endif // __cplusplus

View file

@ -860,13 +860,13 @@ expire_nd_entries(void *unused)
void
add_tgchange(const char *host)
{
tgchange *target;
tgchange::tgchange *target;
rb_patricia_node_t *pnode;
if(find_tgchange(host))
return;
target = (tgchange *)rb_malloc(sizeof(tgchange));
target = (tgchange::tgchange *)rb_malloc(sizeof(tgchange::tgchange));
pnode = make_and_lookup(tgchange_tree, host);
pnode->data = target;
@ -878,13 +878,13 @@ add_tgchange(const char *host)
rb_dlinkAdd(target, &target->node, &tgchange_list);
}
tgchange *
tgchange::tgchange *
find_tgchange(const char *host)
{
rb_patricia_node_t *pnode;
if((pnode = rb_match_exact_string(tgchange_tree, host)))
return (tgchange *)pnode->data;
return (tgchange::tgchange *)pnode->data;
return NULL;
}

View file

@ -628,9 +628,9 @@ register_local_user(client::client *client_p, client::client *source_p)
/* they get a reduced limit */
if(find_tgchange(source_p->sockhost))
source_p->localClient->targets_free = uint(client::tgchange::INITIAL_LOW);
source_p->localClient->targets_free = tgchange::INITIAL_LOW;
else
source_p->localClient->targets_free = uint(client::tgchange::INITIAL);
source_p->localClient->targets_free = tgchange::INITIAL;
monitor_signon(source_p);
user_welcome(source_p);

View file

@ -5,6 +5,7 @@
* Copyright (C) 2004-2005 Lee Hardy <lee@leeh.co.uk>
* Copyright (C) 2005-2010 Jilles Tjoelker <jilles@stack.nl>
* Copyright (C) 2004-2005 ircd-ratbox development team
* Copyright (C) 2016 Charybdis Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,68 +23,125 @@
* USA
*/
namespace ircd {
namespace ircd {
namespace tgchange {
static int add_hashed_target(client::client *source_p, uint32_t hashv);
static bool add_target(client &source, const uint32_t &hashv);
chan::chan *
find_allowing_channel(client::client *source, client::client *target)
} // namespace tgchange
} // namespace ircd;
namespace tgchange = ircd::tgchange;
using ircd::client::client;
using ircd::chan::chan;
chan *
tgchange::find_allowing_channel(client &source,
const client &target)
{
for(const auto &pit : chans(user(*source)))
for(const auto &pit : chans(user(source)))
{
auto &chan(*pit.first);
auto &member(*pit.second);
if ((is_chanop(member) || is_voiced(member)) && is_member(chan, *target))
const auto &member(*pit.second);
if((is_chanop(member) || is_voiced(member)) && is_member(chan, target))
return &chan;
}
return nullptr;
}
int
add_target(client::client *source_p, client::client *target_p)
const chan *
tgchange::find_allowing_channel(const client &source,
const client &target)
{
uint32_t hashv;
for(const auto &pit : chans(user(source)))
{
const auto &chan(*pit.first);
const auto &member(*pit.second);
if((is_chanop(member) || is_voiced(member)) && is_member(chan, target))
return &chan;
}
return nullptr;
}
bool
tgchange::add_target(client &source,
const client &target)
{
/* can msg themselves or services without using any target slots */
if(source_p == target_p || is(*target_p, umode::SERVICE))
return 1;
if(source == target || is(target, umode::SERVICE))
return true;
/* special condition for those who have had PRIVMSG crippled to allow them
* to talk to IRCops still.
*
* XXX: is this controversial?
*/
if(source_p->localClient->target_last > rb_current_time() && is(*target_p, umode::OPER))
return 1;
if(source.localClient->target_last > rb_current_time() && is(target, umode::OPER))
return true;
hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
return add_hashed_target(source_p, hashv);
const auto hashv(fnv_hash_upper(use_id(target), 32));
return add_target(source, hashv);
}
int
add_channel_target(client::client *source_p, chan::chan *chptr)
bool
tgchange::add_target(client &source,
const chan &target)
{
uint32_t hashv;
if(!ConfigChannel.channel_target_change)
return 1;
return true;
hashv = fnv_hash_upper((const unsigned char *)chptr->name.c_str(), 32);
return add_hashed_target(source_p, hashv);
const auto hashv(fnv_hash_upper(name(target).c_str(), 32));
return add_target(source, hashv);
}
static int
add_hashed_target(client::client *source_p, uint32_t hashv)
void
tgchange::add_reply_target(client &source,
const client &target)
{
/* can msg themselves or services without using any target slots */
if(source == target || is(target, umode::SERVICE))
return;
auto &targets(source.localClient->targets);
static_assert(NUM + REPLY == sizeof(targets) / sizeof(uint32_t), "");
/* check for existing target, and move it to the first reply slot
* if it is in a reply slot
*/
const auto hashv(fnv_hash_upper(use_id(target), 32));
for(int i(0); i < NUM + REPLY; i++)
{
if(targets[i] == hashv)
{
if(i > NUM)
{
for(int j(i); j > NUM; j--)
targets[j] = targets[j - 1];
targets[NUM] = hashv;
}
return;
}
}
for(int i(NUM + REPLY - 1); i > NUM; i--)
targets[i] = targets[i - 1];
targets[NUM] = hashv;
}
bool
tgchange::add_target(client &source,
const uint32_t &hashv)
{
int i, j;
uint32_t *targets;
targets = source_p->localClient->targets;
targets = source.localClient->targets;
/* check for existing target, and move it to the head */
for(i = 0; i < int(client::tgchange::NUM) + int(client::tgchange::REPLY); i++)
for(i = 0; i < NUM + REPLY; i++)
{
if(targets[i] == hashv)
{
@ -94,48 +152,46 @@ add_hashed_target(client::client *source_p, uint32_t hashv)
}
}
if(source_p->localClient->targets_free < int(client::tgchange::NUM))
if(source.localClient->targets_free < NUM)
{
/* first message after connect, we may only start clearing
* slots after this message --anfl
*/
if(!is_tg_change(*source_p))
if(!is_tg_change(source))
{
set_tg_change(*source_p);
source_p->localClient->target_last = rb_current_time();
set_tg_change(source);
source.localClient->target_last = rb_current_time();
}
/* clear as many targets as we can */
else if((i = (rb_current_time() - source_p->localClient->target_last) / 60))
else if((i = (rb_current_time() - source.localClient->target_last) / 60))
{
if(i + source_p->localClient->targets_free > int(client::tgchange::NUM))
source_p->localClient->targets_free = int(client::tgchange::NUM);
if(i + source.localClient->targets_free > NUM)
source.localClient->targets_free = NUM;
else
source_p->localClient->targets_free += i;
source.localClient->targets_free += i;
source_p->localClient->target_last = rb_current_time();
source.localClient->target_last = rb_current_time();
}
/* cant clear any, full target list */
else if(source_p->localClient->targets_free == 0)
else if(source.localClient->targets_free == 0)
{
ServerStats.is_tgch++;
add_tgchange(source_p->sockhost);
add_tgchange(source.sockhost);
if (!is_tg_excessive(*source_p))
if (!is_tg_excessive(source))
{
set_tg_excessive(*source_p);
set_tg_excessive(source);
/* This is sent to L_ALL because it's regenerated on all servers
* that have the TGINFO module loaded.
*/
sendto_realops_snomask(SNO_BOTS, L_ALL,
"Excessive target change from %s (%s@%s)",
source_p->name, source_p->username,
source_p->orighost);
source.name, source.username,
source.orighost);
}
sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS,
"ENCAP * TGINFO 0");
return 0;
sendto_match_servs(&source, "*", CAP_ENCAP, NOCAPS, "ENCAP * TGINFO 0");
return false;
}
}
/* no targets in use, reset their target_last so that they cant
@ -143,50 +199,13 @@ add_hashed_target(client::client *source_p, uint32_t hashv)
*/
else
{
source_p->localClient->target_last = rb_current_time();
set_tg_change(*source_p);
source.localClient->target_last = rb_current_time();
set_tg_change(source);
}
for(i = int(client::tgchange::NUM) + int(client::tgchange::REPLY) - 1; i > 0; i--)
for(i = NUM + REPLY - 1; i > 0; i--)
targets[i] = targets[i - 1];
targets[0] = hashv;
source_p->localClient->targets_free--;
return 1;
}
void
add_reply_target(client::client *source_p, client::client *target_p)
{
int i, j;
uint32_t hashv;
uint32_t *targets;
/* can msg themselves or services without using any target slots */
if(source_p == target_p || is(*target_p, umode::SERVICE))
return;
hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
targets = source_p->localClient->targets;
/* check for existing target, and move it to the first reply slot
* if it is in a reply slot
*/
for(i = 0; i < int(client::tgchange::NUM) + int(client::tgchange::REPLY); i++)
{
if(targets[i] == hashv)
{
if(i > int(client::tgchange::NUM))
{
for(j = i; j > int(client::tgchange::NUM); j--)
targets[j] = targets[j - 1];
targets[int(client::tgchange::NUM)] = hashv;
}
return;
}
}
for(i = int(client::tgchange::NUM) + int(client::tgchange::REPLY) - 1; i > int(client::tgchange::NUM); i--)
targets[i] = targets[i - 1];
targets[int(client::tgchange::NUM)] = hashv;
}
source.localClient->targets_free--;
return true;
}

View file

@ -513,7 +513,7 @@ msg_channel(enum message_type msgtype,
{
if(result != chan::CAN_SEND_OPV && my(source) &&
!is(source, umode::OPER) &&
!add_channel_target(&source, chptr))
!tgchange::add_target(source, *chptr))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name,
@ -534,7 +534,7 @@ msg_channel(enum message_type msgtype,
else if(chptr->mode.mode & chan::mode::OPMODERATE &&
(!(chptr->mode.mode & chan::mode::NOPRIVMSGS) || is_member(chptr, &source)))
{
if(my(source) && !is(source, umode::OPER) && !add_channel_target(&source, chptr))
if(my(source) && !is(source, umode::OPER) && !tgchange::add_target(source, *chptr))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name,
@ -683,12 +683,12 @@ msg_channel_flags(enum message_type msgtype, client::client &client,
static void
expire_tgchange(void *unused)
{
tgchange *target;
tgchange::tgchange *target;
rb_dlink_node *ptr, *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, tgchange_list.head)
{
target = (tgchange *)ptr->data;
target = (tgchange::tgchange *)ptr->data;
if(target->expiry < rb_current_time())
{
@ -754,7 +754,7 @@ msg_client(enum message_type msgtype,
/* auto cprivmsg/cnotice */
do_floodcount = !is(source, umode::OPER) &&
!find_allowing_channel(&source, target_p);
!tgchange::find_allowing_channel(source, *target_p);
/* target change stuff, dont limit ctcp replies as that
* would allow people to start filling up random users
@ -763,7 +763,7 @@ msg_client(enum message_type msgtype,
if((msgtype != MESSAGE_TYPE_NOTICE || *text != '\001') &&
ConfigFileEntry.target_change && do_floodcount)
{
if(!add_target(&source, target_p))
if(!tgchange::add_target(source, *target_p))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name, source.name, target_p->name);
@ -823,7 +823,7 @@ msg_client(enum message_type msgtype,
/* Here is the anti-flood bot/spambot code -db */
if(accept_message(&source, target_p) || is(source, umode::OPER))
{
add_reply_target(target_p, &source);
tgchange::add_reply_target(*target_p, source);
sendto_one(target_p, ":%s!%s@%s %s %s :%s",
source.name,
source.username,
@ -854,7 +854,7 @@ msg_client(enum message_type msgtype,
form_str(RPL_TARGNOTIFY),
target_p->name);
add_reply_target(target_p, &source);
tgchange::add_reply_target(*target_p, source);
sendto_one(target_p, form_str(RPL_UMODEGMSG),
me.name, target_p->name, source.name,
source.username, source.host);
@ -865,7 +865,7 @@ msg_client(enum message_type msgtype,
}
else
{
add_reply_target(target_p, &source);
tgchange::add_reply_target(*target_p, source);
sendto_anywhere(target_p, &source, cmdname[msgtype], ":%s", text);
}
}

View file

@ -149,8 +149,8 @@ m_invite(struct MsgBuf *msgbuf_p, client::client &client, client::client &source
if(my_connect(source))
{
if (ConfigFileEntry.target_change && !is(source, umode::OPER) &&
!find_allowing_channel(&source, target_p) &&
!add_target(&source, target_p))
!tgchange::find_allowing_channel(source, *target_p) &&
!tgchange::add_target(source, *target_p))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name, source.name, target_p->name);
@ -200,7 +200,7 @@ m_invite(struct MsgBuf *msgbuf_p, client::client &client, client::client &source
target_p->localClient->last_caller_id_time = rb_current_time();
}
}
add_reply_target(target_p, &source);
tgchange::add_reply_target(*target_p, source);
sendto_one(target_p, ":%s!%s@%s INVITE %s :%s",
source.name, source.username, source.host,
target_p->name, chptr->name.c_str());

View file

@ -98,7 +98,7 @@ m_topic(struct MsgBuf *msgbuf_p, client::client &client, client::client &source,
!is_chanop(msptr) &&
!is_voiced(msptr) &&
!is(source, umode::OPER) &&
!add_channel_target(&source, chptr))
!tgchange::add_target(source, *chptr))
{
sendto_one(&source, form_str(ERR_TARGCHANGE),
me.name, source.name, chptr->name.c_str());