Large diffs are not rendered by default.

@@ -41,67 +41,6 @@
#include "resv.h"


/* do_join_0()
*
* inputs - pointer to client doing join 0
* output - NONE
* side effects - Use has decided to join 0. This is legacy
* from the days when channels were numbers not names. *sigh*
* There is a bunch of evilness necessary here due to
* anti spambot code.
*/
static void
do_join_0(struct Client *source_p)
{
dlink_node *ptr = NULL, *ptr_next = NULL;

DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->channel.head)
{
struct Channel *chptr = ((struct Membership *)ptr->data)->chptr;

sendto_server(source_p, NOCAPS, NOCAPS, ":%s PART %s",
source_p->id, chptr->chname);
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s",
source_p->name, source_p->username,
source_p->host, chptr->chname);

remove_user_from_channel(ptr->data);
}
}

/* last0() stolen from ircu */
static char *
last0(struct Client *target_p, char *chanlist)
{
char *p;
int join0 = 0;

for (p = chanlist; *p; ++p) /* find last "JOIN 0" */
{
if (*p == '0' && (*(p + 1) == ',' || *(p + 1) == '\0'))
{
if ((*p + 1) == ',')
++p;

chanlist = p + 1;
join0 = 1;
}
else
{
while (*p != ',' && *p != '\0') /* skip past channel name */
++p;

if (*p == '\0') /* hit the end */
break;
}
}

if (join0)
do_join_0(target_p);

return chanlist;
}

/*! \brief SVSJOIN command handler
*
* \param source_p Pointer to allocated Client struct from which the message
@@ -118,15 +57,7 @@ last0(struct Client *target_p, char *chanlist)
static int
ms_svsjoin(struct Client *source_p, int parc, char *parv[])
{
char *p = NULL;
char *key_list = NULL;
char *chan_list = NULL;
char *chan = NULL;
struct Channel *chptr = NULL;
struct MaskItem *conf = NULL;
struct Client *target_p = NULL;
int i = 0;
unsigned int flags = 0;

if (!HasFlag(source_p, FLAGS_SERVICE))
return 0;
@@ -137,6 +68,12 @@ ms_svsjoin(struct Client *source_p, int parc, char *parv[])
if ((target_p = find_person(source_p, parv[1])) == NULL)
return 0;

if (MyConnect(target_p))
{
channel_do_join(target_p, parv[2], parv[3]);
return 0;
}

if (target_p->from == source_p->from)
{
sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
@@ -147,161 +84,12 @@ ms_svsjoin(struct Client *source_p, int parc, char *parv[])
return 0;
}

if (!MyConnect(target_p))
{
if (parc == 3)
sendto_one(target_p, ":%s SVSJOIN %s %s", source_p->id,
target_p->id, parv[2]);
else
sendto_one(target_p, ":%s SVSJOIN %s %s %s", source_p->id,
target_p->id, parv[2], parv[3]);
return 0;
}

key_list = parv[3];
chan_list = last0(target_p, parv[2]);

for (chan = strtoken(&p, chan_list, ","); chan;
chan = strtoken(&p, NULL, ","))
{
const char *key = NULL;

/* If we have any more keys, take the first for this channel. */
if (!EmptyString(key_list) && (key_list = strchr(key = key_list, ',')))
*key_list++ = '\0';

/* Empty keys are the same as no keys. */
if (key && *key == '\0')
key = NULL;

if (!check_channel_name(chan, 1))
{
sendto_one_numeric(target_p, &me, ERR_BADCHANNAME, chan);
continue;
}

if (!IsExemptResv(target_p) &&
!(HasUMode(target_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv) &&
((conf = match_find_resv(chan)) && !resv_find_exempt(target_p, conf)))
{
++conf->count;
sendto_one_numeric(target_p, &me, ERR_CHANBANREASON,
chan, conf->reason ? conf->reason : "Reserved channel");
sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
"Forbidding reserved channel %s from user %s",
chan, get_client_name(target_p, HIDE_IP));
continue;
}

if (dlink_list_length(&target_p->channel) >=
(HasUMode(target_p, UMODE_OPER) ?
ConfigChannel.max_chans_per_oper :
ConfigChannel.max_chans_per_user))
{
sendto_one_numeric(target_p, &me, ERR_TOOMANYCHANNELS, chan);
break;
}

if ((chptr = hash_find_channel(chan)))
{
if (IsMember(target_p, chptr))
continue;

if (splitmode && !HasUMode(target_p, UMODE_OPER) &&
ConfigChannel.no_join_on_split)
{
sendto_one_numeric(target_p, &me, ERR_UNAVAILRESOURCE, chan);
continue;
}

/*
* can_join checks for +i key, bans.
*/
if ((i = can_join(target_p, chptr, key)))
{
sendto_one_numeric(target_p, &me, i, chptr->chname);
continue;
}

/*
* This should never be the case unless there is some sort of
* persistant channels.
*/
if (dlink_list_length(&chptr->members) == 0)
flags = CHFL_CHANOP;
else
flags = 0;
}
else
{
if (splitmode && !HasUMode(target_p, UMODE_OPER) &&
(ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
{
sendto_one_numeric(target_p, &me, ERR_UNAVAILRESOURCE, chan);
continue;
}

flags = CHFL_CHANOP;
chptr = make_channel(chan);
}

add_user_to_channel(chptr, target_p, flags, 1);

/*
* Set timestamp if appropriate, and propagate
*/
if (flags == CHFL_CHANOP)
{
chptr->channelts = CurrentTime;
chptr->mode.mode |= MODE_TOPICLIMIT;
chptr->mode.mode |= MODE_NOPRIVMSGS;

sendto_server(target_p, NOCAPS, NOCAPS, ":%s SJOIN %lu %s +nt :@%s",
me.id, (unsigned long)chptr->channelts,
chptr->chname, target_p->id);
/*
* Notify all other users on the new channel
*/
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s",
target_p->name, target_p->username,
target_p->host, chptr->chname);
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +nt",
me.name, chptr->chname);

if (target_p->away[0])
sendto_channel_local_butone(target_p, 0, CAP_AWAY_NOTIFY, chptr,
":%s!%s@%s AWAY :%s",
target_p->name, target_p->username,
target_p->host, target_p->away);
}
else
{
sendto_server(target_p, NOCAPS, NOCAPS, ":%s JOIN %lu %s +",
target_p->id, (unsigned long)chptr->channelts,
chptr->chname);
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s",
target_p->name, target_p->username,
target_p->host, chptr->chname);

if (target_p->away[0])
sendto_channel_local_butone(target_p, 0, CAP_AWAY_NOTIFY, chptr,
":%s!%s@%s AWAY :%s",
target_p->name, target_p->username,
target_p->host, target_p->away);
}

del_invite(chptr, target_p);

if (chptr->topic[0])
{
sendto_one_numeric(target_p, &me, RPL_TOPIC, chptr->chname, chptr->topic);
sendto_one_numeric(target_p, &me, RPL_TOPICWHOTIME, chptr->chname,
chptr->topic_info, chptr->topic_time);
}

channel_member_names(target_p, chptr, 1);
}

if (parc == 3)
sendto_one(target_p, ":%s SVSJOIN %s %s", source_p->id,
target_p->id, parv[2]);
else
sendto_one(target_p, ":%s SVSJOIN %s %s %s", source_p->id,
target_p->id, parv[2], parv[3]);
return 0;
}

@@ -163,7 +163,7 @@ ms_svsmode(struct Client *source_p, int parc, char *parv[])
{
char modebuf[IRCD_BUFSIZE] = "";

send_umode(target_p, target_p, setmodes, 0xffffffff, modebuf);
send_umode(target_p, target_p, setmodes, modebuf);
}

return 0;
@@ -63,14 +63,25 @@ ms_svsnick(struct Client *source_p, int parc, char *parv[])
if (!HasFlag(source_p, FLAGS_SERVICE) || !valid_nickname(parv[2], 1))
return 0;

if (hunt_server(source_p, ":%s SVSNICK %s %s :%s",
1, parc, parv) != HUNTED_ISME)
return 0;

if ((target_p = find_person(source_p, parv[1])) == NULL)
return 0;

assert(MyClient(target_p));
if (!MyConnect(target_p))
{
if (target_p->from == source_p->from)
{
sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
"Received wrong-direction SVSNICK "
"for %s (behind %s) from %s",
target_p->name, source_p->from->name,
get_client_name(source_p, HIDE_IP));
return 0;
}

sendto_one(target_p, ":%s SVSNICK %s %s %s", source_p->id,
target_p->id, parv[2], parv[3]);
return 0;
}

if ((exists_p = hash_find_client(parv[2])))
{
@@ -98,7 +109,7 @@ ms_svsnick(struct Client *source_p, int parc, char *parv[])
char modebuf[IRCD_BUFSIZE] = "";

DelUMode(target_p, UMODE_REGISTERED);
send_umode(target_p, target_p, oldmodes, 0xffffffff, modebuf);
send_umode(target_p, target_p, oldmodes, modebuf);
}

sendto_common_channels_local(target_p, 1, 0, ":%s!%s@%s NICK :%s",
@@ -39,56 +39,6 @@
#include "packet.h"


/*! \brief Removes a client from a specific channel
* \param source_p Pointer to source client to remove
* \param name Name of channel to remove from
* \param reason Part reason to show
*/
static void
part_one_client(struct Client *target_p, const char *name, const char *reason)
{
struct Channel *chptr = NULL;
struct Membership *ms = NULL;

if ((chptr = hash_find_channel(name)) == NULL)
{
sendto_one_numeric(target_p, &me, ERR_NOSUCHCHANNEL, name);
return;
}

if ((ms = find_channel_link(target_p, chptr)) == NULL)
{
sendto_one_numeric(target_p, &me, ERR_NOTONCHANNEL, chptr->chname);
return;
}

/*
* Remove user from the old channel (if any)
* only allow /part reasons in -m chans
*/
if (*reason && (!MyConnect(target_p) ||
((can_send(chptr, target_p, ms, reason) &&
(target_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time)
< CurrentTime))))
{
sendto_server(target_p, NOCAPS, NOCAPS, ":%s PART %s :%s",
target_p->id, chptr->chname, reason);
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s :%s",
target_p->name, target_p->username,
target_p->host, chptr->chname, reason);
}
else
{
sendto_server(target_p, NOCAPS, NOCAPS, ":%s PART %s",
target_p->id, chptr->chname);
sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s",
target_p->name, target_p->username,
target_p->host, chptr->chname);
}

remove_user_from_channel(ms);
}

/*! \brief SVSPART command handler
*
* \param source_p Pointer to allocated Client struct from which the message
@@ -106,8 +56,6 @@ static int
ms_svspart(struct Client *source_p, int parc, char *parv[])
{
struct Client *target_p = NULL;
char *p = NULL, *name = NULL;
char reason[KICKLEN + 1] = "";

if (!HasFlag(source_p, FLAGS_SERVICE))
return 0;
@@ -118,6 +66,12 @@ ms_svspart(struct Client *source_p, int parc, char *parv[])
if ((target_p = find_person(source_p, parv[1])) == NULL)
return 0;

if (MyConnect(target_p))
{
channel_do_part(target_p, parv[2], parv[3]);
return 0;
}

if (target_p->from == source_p->from)
{
sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
@@ -128,23 +82,12 @@ ms_svspart(struct Client *source_p, int parc, char *parv[])
return 0;
}

if (!MyConnect(target_p))
{
if (parc == 3)
sendto_one(target_p, ":%s SVSPART %s %s", source_p->id,
target_p->id, parv[2]);
else
sendto_one(target_p, ":%s SVSPART %s %s :%s", source_p->id,
target_p->id, parv[2], parv[3]);
return 0;
}

if (parc > 3 && !EmptyString(parv[3]))
strlcpy(reason, parv[3], sizeof(reason));

for (name = strtoken(&p, parv[2], ","); name;
name = strtoken(&p, NULL, ","))
part_one_client(target_p, name, reason);
if (parc == 3)
sendto_one(target_p, ":%s SVSPART %s %s", source_p->id,
target_p->id, parv[2]);
else
sendto_one(target_p, ":%s SVSPART %s %s :%s", source_p->id,
target_p->id, parv[2], parv[3]);
return 0;
}

@@ -97,7 +97,7 @@ ms_tburst(struct Client *source_p, int parc, char *parv[])
int topic_differs = strncmp(chptr->topic, topic, sizeof(chptr->topic) - 1);
int hidden_server = (ConfigServerHide.hide_servers || IsHidden(source_p));

set_channel_topic(chptr, topic, setby, remote_topic_ts, 0);
channel_set_topic(chptr, topic, setby, remote_topic_ts, 0);

sendto_server(source_p, CAP_TBURST, NOCAPS,
":%s TBURST %s %s %s %s :%s",
@@ -89,7 +89,7 @@ m_topic(struct Client *source_p, int parc, char *parv[])

snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
source_p->username, source_p->host);
set_channel_topic(chptr, parv[2], topic_info, CurrentTime, 1);
channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 1);

sendto_server(source_p, NOCAPS, NOCAPS, ":%s TOPIC %s :%s",
source_p->id, chptr->chname,
@@ -162,7 +162,7 @@ ms_topic(struct Client *source_p, int parc, char *parv[])
else
snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
source_p->username, source_p->host);
set_channel_topic(chptr, parv[2], topic_info, CurrentTime, 0);
channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 0);

sendto_server(source_p, NOCAPS, NOCAPS, ":%s TOPIC %s :%s",
source_p->id, chptr->chname,
@@ -97,7 +97,7 @@ remove_dline_match(const char *host)
static int
mo_undline(struct Client *source_p, int parc, char *parv[])
{
char *addr = NULL, *user = NULL;
char *addr = NULL;
char *target_server = NULL;

if (!HasOFlag(source_p, OPER_FLAG_UNDLINE))
@@ -112,8 +112,8 @@ mo_undline(struct Client *source_p, int parc, char *parv[])
return 0;
}

if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user,
&addr, NULL, &target_server, NULL) < 0)
if (parse_aline("UNDLINE", source_p, parc, parv, 0, &addr,
NULL, NULL, &target_server, NULL) < 0)
return 0;

if (target_server)
@@ -140,7 +140,7 @@ mo_unkline(struct Client *source_p, int parc, char *parv[])
get_oper_name(source_p), user, host);
}
else
sendto_one_notice(source_p, &me, ":No K-Line for [%s@%s] found",
sendto_one_notice(source_p, &me, ":No K-Line for [%s@%s] found",
user, host);
return 0;
}
@@ -141,7 +141,7 @@ mo_unxline(struct Client *source_p, int parc, char *parv[])
* \note Valid arguments for this command are:
* - parv[0] = command
* - parv[1] = target server
* - parv[2] = gecos
* - parv[2] = gecos
*/
static int
ms_unxline(struct Client *source_p, int parc, char *parv[])
@@ -63,7 +63,7 @@ mo_wallops(struct Client *source_p, int parc, char *parv[])
return 0;
}

sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message);
sendto_wallops_flags(UMODE_WALLOP, source_p, "%s", message);
sendto_server(source_p, NOCAPS, NOCAPS, ":%s WALLOPS :%s",
source_p->id, message);
return 0;
@@ -88,11 +88,7 @@ ms_wallops(struct Client *source_p, int parc, char *parv[])
if (EmptyString(message))
return 0;

if (IsClient(source_p))
sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message);
else
sendto_wallops_flags(UMODE_WALLOP, source_p, "%s", message);

sendto_wallops_flags(UMODE_WALLOP, source_p, "%s", message);
sendto_server(source_p, NOCAPS, NOCAPS, ":%s WALLOPS :%s",
source_p->id, message);
return 0;
@@ -91,8 +91,8 @@ do_who(struct Client *source_p, struct Client *target_p,
*
*/
static void
who_common_channel(struct Client *source_p, struct Channel *chptr,
char *mask, int server_oper, int *maxmatches)
who_common_channel(struct Client *source_p, struct Channel *chptr, char *mask,
int server_oper, unsigned int *maxmatches)
{
dlink_node *ptr = NULL;

@@ -143,7 +143,7 @@ who_global(struct Client *source_p, char *mask, int server_oper)
struct Channel *chptr;
struct Client *target_p;
dlink_node *lp = NULL, *gcptr = NULL;
int maxmatches = 500;
unsigned int maxmatches = 500;
static time_t last_used = 0;

if (!HasUMode(source_p, UMODE_OPER))
@@ -76,7 +76,7 @@ valid_xline(struct Client *source_p, const char *gecos, const char *reason, int
if (!valid_wild_card_simple(gecos))
{
if (warn)
sendto_one_notice(source_p, &me, ":Please include at least %d non-wildcard characters with the xline",
sendto_one_notice(source_p, &me, ":Please include at least %u non-wildcard characters with the xline",
ConfigFileEntry.min_nonwildcard_simple);

return 0;
@@ -24,7 +24,6 @@ ircd_SOURCES = auth.c \
getopt.c \
gline.c \
hash.c \
hook.c \
hostmask.c \
irc_string.c \
ircd.c \
@@ -90,6 +90,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_openssl.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/gcc_stack_protect.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -108,19 +109,18 @@ am_ircd_OBJECTS = auth.$(OBJEXT) channel.$(OBJEXT) \
conf_class.$(OBJEXT) conf_db.$(OBJEXT) conf_parser.$(OBJEXT) \
conf_lexer.$(OBJEXT) dbuf.$(OBJEXT) event.$(OBJEXT) \
fdlist.$(OBJEXT) getopt.$(OBJEXT) gline.$(OBJEXT) \
hash.$(OBJEXT) hook.$(OBJEXT) hostmask.$(OBJEXT) \
irc_string.$(OBJEXT) ircd.$(OBJEXT) ircd_signal.$(OBJEXT) \
list.$(OBJEXT) listener.$(OBJEXT) log.$(OBJEXT) \
match.$(OBJEXT) memory.$(OBJEXT) mempool.$(OBJEXT) \
misc.$(OBJEXT) modules.$(OBJEXT) motd.$(OBJEXT) \
numeric.$(OBJEXT) packet.$(OBJEXT) parse.$(OBJEXT) \
s_bsd_epoll.$(OBJEXT) s_bsd_poll.$(OBJEXT) \
s_bsd_devpoll.$(OBJEXT) s_bsd_kqueue.$(OBJEXT) \
s_bsd_select.$(OBJEXT) res.$(OBJEXT) reslib.$(OBJEXT) \
restart.$(OBJEXT) resv.$(OBJEXT) rng_mt.$(OBJEXT) \
rsa.$(OBJEXT) s_bsd.$(OBJEXT) send.$(OBJEXT) server.$(OBJEXT) \
user.$(OBJEXT) version.$(OBJEXT) watch.$(OBJEXT) \
whowas.$(OBJEXT)
hash.$(OBJEXT) hostmask.$(OBJEXT) irc_string.$(OBJEXT) \
ircd.$(OBJEXT) ircd_signal.$(OBJEXT) list.$(OBJEXT) \
listener.$(OBJEXT) log.$(OBJEXT) match.$(OBJEXT) \
memory.$(OBJEXT) mempool.$(OBJEXT) misc.$(OBJEXT) \
modules.$(OBJEXT) motd.$(OBJEXT) numeric.$(OBJEXT) \
packet.$(OBJEXT) parse.$(OBJEXT) s_bsd_epoll.$(OBJEXT) \
s_bsd_poll.$(OBJEXT) s_bsd_devpoll.$(OBJEXT) \
s_bsd_kqueue.$(OBJEXT) s_bsd_select.$(OBJEXT) res.$(OBJEXT) \
reslib.$(OBJEXT) restart.$(OBJEXT) resv.$(OBJEXT) \
rng_mt.$(OBJEXT) rsa.$(OBJEXT) s_bsd.$(OBJEXT) send.$(OBJEXT) \
server.$(OBJEXT) user.$(OBJEXT) version.$(OBJEXT) \
watch.$(OBJEXT) whowas.$(OBJEXT)
ircd_OBJECTS = $(am_ircd_OBJECTS)
am__DEPENDENCIES_1 =
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -372,7 +372,6 @@ ircd_SOURCES = auth.c \
getopt.c \
gline.c \
hash.c \
hook.c \
hostmask.c \
irc_string.c \
ircd.c \
@@ -520,7 +519,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gline.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hook.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostmask.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc_string.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ircd.Po@am__quote@
@@ -81,7 +81,7 @@ enum

static dlink_list auth_doing_list = { NULL, NULL, 0 };

static EVH timeout_auth_queries_event;
static void timeout_auth_queries_event(void *);

static PF read_auth_reply;
static CNCB auth_connect_callback;
@@ -93,7 +93,14 @@ static CNCB auth_connect_callback;
void
auth_init(void)
{
eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
static struct event timeout_auth_queries =
{
.name = "timeout_auth_queries_event",
.handler = timeout_auth_queries_event,
.when = 1
};

event_add(&timeout_auth_queries, NULL);
}

/*
@@ -550,7 +557,7 @@ read_auth_reply(fde_t *fd, void *data)
{
if (*s == '@')
break;
if (!IsSpace(*s) && *s != ':' && *s != '[')
if (!IsSpace(*s) && *s != ':')
{
*t++ = *s;
count--;

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -60,7 +60,7 @@ dlink_list serv_list = {NULL, NULL, 0};
dlink_list global_serv_list = {NULL, NULL, 0};
dlink_list oper_list = {NULL, NULL, 0};

static EVH check_pings;
static void check_pings(void *);

static mp_pool_t *client_pool = NULL;
static mp_pool_t *lclient_pool = NULL;
@@ -83,12 +83,16 @@ static void check_unknowns_list(void);
void
client_init(void)
{
/* start off the check ping event .. -- adrian
* Every 30 seconds is plenty -- db
*/
static struct event event_ping =
{
.name = "check_pings",
.handler = check_pings,
.when = 5
};

client_pool = mp_pool_new(sizeof(struct Client), MP_CHUNK_SIZE_CLIENT);
lclient_pool = mp_pool_new(sizeof(struct LocalUser), MP_CHUNK_SIZE_LCLIENT);
eventAdd("check_pings", check_pings, NULL, 5);
event_add(&event_ping, NULL);
}

/*
@@ -111,15 +115,10 @@ make_client(struct Client *from)
{
struct Client *client_p = mp_pool_get(client_pool);

memset(client_p, 0, sizeof(*client_p));

if (!from)
{
client_p->from = client_p; /* 'from' of local client is self! */
client_p->localClient = mp_pool_get(lclient_pool);

memset(client_p->localClient, 0, sizeof(*client_p->localClient));

client_p->localClient->since = CurrentTime;
client_p->localClient->lasttime = CurrentTime;
client_p->localClient->firsttime = CurrentTime;
@@ -334,25 +333,21 @@ check_unknowns_list(void)
void
check_conf_klines(void)
{
struct Client *client_p = NULL; /* current local client_p being examined */
struct MaskItem *conf = NULL;
dlink_node *ptr, *next_ptr;
dlink_node *ptr = NULL, *ptr_next = NULL;

DLINK_FOREACH_SAFE(ptr, next_ptr, local_client_list.head)
DLINK_FOREACH_SAFE(ptr, ptr_next, local_client_list.head)
{
client_p = ptr->data;
struct Client *client_p = ptr->data;

/* If a client is already being exited
*/
if (IsDead(client_p) || !IsClient(client_p))
continue;

if ((conf = find_dline_conf(&client_p->localClient->ip,
client_p->localClient->aftype)))
if ((conf = find_conf_by_address(NULL, &client_p->localClient->ip, CONF_DLINE,
client_p->localClient->aftype, NULL, NULL, 1)))
{
if (conf->type == CONF_EXEMPT)
continue;

conf_try_ban(client_p, conf);
continue; /* and go examine next fd/client_p */
}
@@ -386,17 +381,15 @@ check_conf_klines(void)
}

/* also check the unknowns list for new dlines */
DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head)
DLINK_FOREACH_SAFE(ptr, ptr_next, unknown_list.head)
{
client_p = ptr->data;
struct Client *client_p = ptr->data;

if ((conf = find_dline_conf(&client_p->localClient->ip,
client_p->localClient->aftype)))
if ((conf = find_conf_by_address(NULL, &client_p->localClient->ip, CONF_DLINE,
client_p->localClient->aftype, NULL, NULL, 1)))
{
if (conf->type == CONF_EXEMPT)
continue;

exit_client(client_p, "D-lined");
conf_try_ban(client_p, conf);
continue; /* and go examine next fd/client_p */
}
}
}
@@ -433,6 +426,9 @@ conf_try_ban(struct Client *client_p, struct MaskItem *conf)
type_string = kline_string;
break;
case CONF_DLINE:
if (find_conf_by_address(NULL, &client_p->localClient->ip, CONF_EXEMPT,
client_p->localClient->aftype, NULL, NULL, 1))
return;
type_string = dline_string;
break;
case CONF_GLINE:
@@ -580,7 +576,7 @@ get_client_name(const struct Client *client_p, enum addr_mask_type type)
}

if (ConfigFileEntry.hide_spoof_ips)
if (type == SHOW_IP && IsIPSpoof(client_p))
if (IsIPSpoof(client_p) && type == SHOW_IP)
type = MASK_IP;

/* And finally, let's get the host information, ip or name */
@@ -681,12 +677,8 @@ exit_one_client(struct Client *source_p, const char *quitmsg)
if (IsUserHostIp(source_p))
delete_user_host(source_p->username, source_p->host, !MyConnect(source_p));

/* remove from global client list
* NOTE: source_p->node.next cannot be NULL if the client is added
* to global_client_list (there is always &me at its end)
*/
if (source_p->node.next) /* XXX: not needed? */
dlinkDelete(&source_p->node, &global_client_list);
assert(source_p->node.next);
dlinkDelete(&source_p->node, &global_client_list);

update_client_exit_stats(source_p);

@@ -56,13 +56,6 @@
#include "motd.h"


struct config_channel_entry ConfigChannel;
struct config_server_hide ConfigServerHide;
struct config_file_entry ConfigFileEntry;
struct logging_entry ConfigLoggingEntry = { .use_logging = 1 };
struct server_info ServerInfo;
struct admin_info AdminInfo;

/* general conf items link list root, other than k lines etc. */
dlink_list service_items = { NULL, NULL, 0 };
dlink_list server_items = { NULL, NULL, 0 };
@@ -71,15 +64,13 @@ dlink_list oconf_items = { NULL, NULL, 0 };
dlink_list uconf_items = { NULL, NULL, 0 };
dlink_list xconf_items = { NULL, NULL, 0 };
dlink_list nresv_items = { NULL, NULL, 0 };
dlink_list cresv_items = { NULL, NULL, 0 };
dlink_list cresv_items = { NULL, NULL, 0 };

extern unsigned int lineno;
extern char linebuf[];
extern char conffilebuf[IRCD_BUFSIZE];
extern int yyparse(); /* defined in y.tab.c */

struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };

/* internally defined functions */
static void read_conf(FILE *);
static void clear_out_old_conf(void);
@@ -102,8 +93,9 @@ static int find_user_host(struct Client *, char *, char *, char *, unsigned int)
struct ip_entry
{
struct irc_ssaddr ip;
unsigned int count;
time_t last_attempt;
unsigned int count; /**< Number of registered users using this IP */
unsigned int connection_count; /**< Number of connections from this IP in the last throttle_time duration */
time_t last_attempt; /**< The last time someone connected from this IP */
struct ip_entry *next;
};

@@ -487,7 +479,7 @@ find_or_add_ip(struct irc_ssaddr *ip_in)
garbage_collect_ip_entries();

newptr = mp_pool_get(ip_entry_pool);
memset(newptr, 0, sizeof(*newptr));

ip_entries_count++;
memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));

@@ -1046,8 +1038,7 @@ rehash(int sig)
strlcpy(me.info, ServerInfo.description, sizeof(me.info));

load_conf_modules();

rehashed_klines = 1;
check_conf_klines();

return 0;
}
@@ -1070,6 +1061,7 @@ set_default_conf(void)
assert(class_default == class_get_list()->tail->data);

#ifdef HAVE_LIBCRYPTO
ServerInfo.message_digest_algorithm = EVP_sha256();
ServerInfo.rsa_private_key = NULL;
ServerInfo.rsa_private_key_file = NULL;
#endif
@@ -1101,10 +1093,12 @@ set_default_conf(void)
ConfigLoggingEntry.use_logging = 1;

ConfigChannel.disable_fake_channels = 0;
ConfigChannel.knock_delay = 300;
ConfigChannel.invite_client_count = 10;
ConfigChannel.invite_client_time = 300;
ConfigChannel.knock_client_count = 1;
ConfigChannel.knock_client_time = 300;
ConfigChannel.knock_delay_channel = 60;
ConfigChannel.max_chans_per_user = 25;
ConfigChannel.max_chans_per_oper = 50;
ConfigChannel.max_channels = 25;
ConfigChannel.max_bans = 25;
ConfigChannel.default_split_user_count = 0;
ConfigChannel.default_split_server_count = 0;
@@ -1147,6 +1141,7 @@ set_default_conf(void)
ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
ConfigFileEntry.warn_no_connect_block = 1;
ConfigFileEntry.stats_e_disabled = 0;
ConfigFileEntry.stats_o_oper_only = 0;
ConfigFileEntry.stats_k_oper_only = 1; /* 1 = masked */
ConfigFileEntry.stats_i_oper_only = 1; /* 1 = masked */
@@ -1163,11 +1158,11 @@ set_default_conf(void)
ConfigFileEntry.oper_pass_resv = 1;
ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
UMODE_OPERWALL | UMODE_WALLOP;
ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | UMODE_WALLOP;
ConfigFileEntry.use_egd = 0;
ConfigFileEntry.egdpool_path = NULL;
ConfigFileEntry.throttle_time = 10;
ConfigFileEntry.throttle_count = 1;
ConfigFileEntry.throttle_time = 1;
}

static void
@@ -1262,7 +1257,7 @@ lookup_confhost(struct MaskItem *conf)
int
conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
{
struct ip_entry *ip_found;
struct ip_entry *ip_found = NULL;
struct MaskItem *conf = find_dline_conf(addr, aftype);

/* DLINE exempt also gets you out of static limits/pacing... */
@@ -1274,12 +1269,15 @@ conf_connect_allowed(struct irc_ssaddr *addr, int aftype)

ip_found = find_or_add_ip(addr);

if ((CurrentTime - ip_found->last_attempt) <
ConfigFileEntry.throttle_time)
if ((CurrentTime - ip_found->last_attempt) < ConfigFileEntry.throttle_time)
{
ip_found->last_attempt = CurrentTime;
return TOO_FAST;
if (ip_found->connection_count >= ConfigFileEntry.throttle_count)
return TOO_FAST;

++ip_found->connection_count;
}
else
ip_found->connection_count = 1;

ip_found->last_attempt = CurrentTime;
return 0;
@@ -1353,8 +1351,7 @@ static const struct oper_privs
{ OPER_FLAG_DIE, 'D' },
{ OPER_FLAG_GLINE, 'G' },
{ OPER_FLAG_REHASH, 'H' },
{ OPER_FLAG_K, 'K' },
{ OPER_FLAG_OPERWALL, 'L' },
{ OPER_FLAG_KLINE, 'K' },
{ OPER_FLAG_KILL, 'N' },
{ OPER_FLAG_KILL_REMOTE, 'O' },
{ OPER_FLAG_CONNECT, 'P' },
@@ -1481,9 +1478,9 @@ read_conf_files(int cold)
add_isupport("CHANTYPES", "#", -1);

snprintf(chanlimit, sizeof(chanlimit), "#:%d",
ConfigChannel.max_chans_per_user);
ConfigChannel.max_channels);
add_isupport("CHANLIMIT", chanlimit, -1);
snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstMORS");
add_isupport("CHANNELLEN", NULL, CHANNELLEN);
add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
add_isupport("CHANMODES", chanmodes, -1);
@@ -1573,15 +1570,6 @@ clear_out_old_conf(void)

MyFree(ServerInfo.rsa_private_key_file);
ServerInfo.rsa_private_key_file = NULL;

if (ServerInfo.server_ctx)
SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
SSL_OP_NO_SSLv3|
SSL_OP_NO_TLSv1);
if (ServerInfo.client_ctx)
SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
SSL_OP_NO_SSLv3|
SSL_OP_NO_TLSv1);
#endif

/* clean out AdminInfo */
@@ -1734,7 +1722,7 @@ valid_wild_card_simple(const char *data)
{
const unsigned char *p = (const unsigned char *)data;
unsigned char tmpch = '\0';
int nonwild = 0;
unsigned int nonwild = 0;

while ((tmpch = *p++))
{
@@ -1765,8 +1753,8 @@ valid_wild_card_simple(const char *data)
int
valid_wild_card(struct Client *source_p, int warn, int count, ...)
{
char tmpch;
int nonwild = 0;
unsigned char tmpch = '\0';
unsigned int nonwild = 0;
va_list args;

/*
@@ -1785,7 +1773,7 @@ valid_wild_card(struct Client *source_p, int warn, int count, ...)

while (count--)
{
const char *p = va_arg(args, const char *);
const unsigned char *p = va_arg(args, const unsigned char *);
if (p == NULL)
continue;

@@ -1808,7 +1796,7 @@ valid_wild_card(struct Client *source_p, int warn, int count, ...)

if (warn)
sendto_one_notice(source_p, &me,
":Please include at least %d non-wildcard characters with the mask",
":Please include at least %u non-wildcard characters with the mask",
ConfigFileEntry.min_nonwildcard);
va_end(args);
return 0;
@@ -2017,7 +2005,7 @@ find_user_host(struct Client *source_p, char *user_host_or_nick,
/* Okay to use source_p as the first param, because source_p == client_p */
if ((target_p =
find_chasing(source_p, user_host_or_nick)) == NULL)
return 0;
return 0; /* find_chasing sends ERR_NOSUCHNICK */

if (IsExemptKline(target_p))
{

Large diffs are not rendered by default.

@@ -208,6 +208,8 @@ hub_mask { return HUB_MASK; }
ignore_bogus_ts { return IGNORE_BOGUS_TS; }
invisible { return T_INVISIBLE; }
invisible_on_connect { return INVISIBLE_ON_CONNECT; }
invite_client_count { return INVITE_CLIENT_COUNT; }
invite_client_time { return INVITE_CLIENT_TIME; }
ip { return IP; }
ipv4 { return T_IPV4; }
ipv6 { return T_IPV6; }
@@ -217,7 +219,8 @@ kill { return KILL; }
kill_chase_time_limit { return KILL_CHASE_TIME_LIMIT; }
kline { return KLINE; }
kline_exempt { return KLINE_EXEMPT; }
knock_delay { return KNOCK_DELAY; }
knock_client_count { return KNOCK_CLIENT_COUNT; }
knock_client_time { return KNOCK_CLIENT_TIME; }
knock_delay_channel { return KNOCK_DELAY_CHANNEL; }
leaf_mask { return LEAF_MASK; }
links_delay { return LINKS_DELAY; }
@@ -228,8 +231,7 @@ mask { return MASK; }
masked { return TMASKED; }
max_accept { return MAX_ACCEPT; }
max_bans { return MAX_BANS; }
max_chans_per_oper { return MAX_CHANS_PER_OPER; }
max_chans_per_user { return MAX_CHANS_PER_USER; }
max_channels { return MAX_CHANNELS; }
max_clients { return T_MAX_CLIENTS; }
max_global { return MAX_GLOBAL; }
max_ident { return MAX_IDENT; }
@@ -268,7 +270,6 @@ oper_pass_resv { return OPER_PASS_RESV; }
oper_umodes { return OPER_UMODES; }
operator { return OPERATOR; }
opers_bypass_callerid { return OPERS_BYPASS_CALLERID; }
operwall { return T_OPERWALL; }
pace_wait { return PACE_WAIT; }
pace_wait_simple { return PACE_WAIT_SIMPLE; }
passwd { return PASSWORD; }
@@ -315,20 +316,19 @@ ssl { return T_SSL; }
ssl_certificate_file { return SSL_CERTIFICATE_FILE; }
ssl_certificate_fingerprint { return SSL_CERTIFICATE_FINGERPRINT; }
ssl_cipher_list { return T_SSL_CIPHER_LIST; }
ssl_client_method { return T_SSL_CLIENT_METHOD; }
ssl_connection_required { return SSL_CONNECTION_REQUIRED; }
ssl_dh_elliptic_curve { return SSL_DH_ELLIPTIC_CURVE; }
ssl_dh_param_file { return SSL_DH_PARAM_FILE; }
ssl_server_method { return T_SSL_SERVER_METHOD; }
sslv3 { return T_SSLV3; }
ssl_message_digest_algorithm { return SSL_MESSAGE_DIGEST_ALGORITHM; }
stats_e_disabled { return STATS_E_DISABLED; }
stats_i_oper_only { return STATS_I_OPER_ONLY; }
stats_k_oper_only { return STATS_K_OPER_ONLY; }
stats_o_oper_only { return STATS_O_OPER_ONLY; }
stats_P_oper_only { return STATS_P_OPER_ONLY; }
stats_u_oper_only { return STATS_U_OPER_ONLY; }
throttle_count { return THROTTLE_COUNT; }
throttle_time { return THROTTLE_TIME; }
tkline_expire_notices { return TKLINE_EXPIRE_NOTICES; }
tlsv1 { return T_TLSV1; }
true_no_oper_flood { return TRUE_NO_OPER_FLOOD; }
ts_max_delta { return TS_MAX_DELTA; }
ts_warn_delta { return TS_WARN_DELTA; }

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -107,6 +107,7 @@ static struct
max_ident,
max_sendq,
max_recvq,
max_channels,
cidr_bitlen_ipv4,
cidr_bitlen_ipv6,
number_per_cidr;
@@ -206,6 +207,8 @@ reset_block_state(void)
%token HUB_MASK
%token IGNORE_BOGUS_TS
%token INVISIBLE_ON_CONNECT
%token INVITE_CLIENT_COUNT
%token INVITE_CLIENT_TIME
%token IP
%token IRCD_AUTH
%token IRCD_FLAGS
@@ -216,16 +219,16 @@ reset_block_state(void)
%token KILL_CHASE_TIME_LIMIT
%token KLINE
%token KLINE_EXEMPT
%token KNOCK_DELAY
%token KNOCK_CLIENT_COUNT
%token KNOCK_CLIENT_TIME
%token KNOCK_DELAY_CHANNEL
%token LEAF_MASK
%token LINKS_DELAY
%token LISTEN
%token MASK
%token MAX_ACCEPT
%token MAX_BANS
%token MAX_CHANS_PER_OPER
%token MAX_CHANS_PER_USER
%token MAX_CHANNELS
%token MAX_GLOBAL
%token MAX_IDENT
%token MAX_IDLE
@@ -292,7 +295,9 @@ reset_block_state(void)
%token SSL_CERTIFICATE_FILE
%token SSL_CERTIFICATE_FINGERPRINT
%token SSL_CONNECTION_REQUIRED
%token SSL_DH_ELLIPTIC_CURVE
%token SSL_DH_PARAM_FILE
%token SSL_MESSAGE_DIGEST_ALGORITHM
%token STATS_E_DISABLED
%token STATS_I_OPER_ONLY
%token STATS_K_OPER_ONLY
@@ -320,7 +325,6 @@ reset_block_state(void)
%token T_MAX_CLIENTS
%token T_NCHANGE
%token T_NONONREG
%token T_OPERWALL
%token T_RECVQ
%token T_REJ
%token T_RESTART
@@ -336,10 +340,6 @@ reset_block_state(void)
%token T_SPY
%token T_SSL
%token T_SSL_CIPHER_LIST
%token T_SSL_CLIENT_METHOD
%token T_SSL_SERVER_METHOD
%token T_SSLV3
%token T_TLSV1
%token T_UMODES
%token T_UNAUTH
%token T_UNDLINE
@@ -350,6 +350,7 @@ reset_block_state(void)
%token T_WALLOPS
%token T_WEBIRC
%token TBOOL
%token THROTTLE_COUNT
%token THROTTLE_TIME
%token TKLINE_EXPIRE_NOTICES
%token TMASKED
@@ -459,49 +460,16 @@ serverinfo_item: serverinfo_name |
serverinfo_max_nick_length |
serverinfo_max_topic_length |
serverinfo_ssl_dh_param_file |
serverinfo_ssl_dh_elliptic_curve |
serverinfo_rsa_private_key_file |
serverinfo_vhost6 |
serverinfo_sid |
serverinfo_ssl_certificate_file |
serverinfo_ssl_client_method |
serverinfo_ssl_server_method |
serverinfo_ssl_cipher_list |
serverinfo_ssl_message_digest_algorithm |
error ';' ;


serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;

client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
client_method_type_item: T_SSLV3
{
#ifdef HAVE_LIBCRYPTO
if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
#endif
} | T_TLSV1
{
#ifdef HAVE_LIBCRYPTO
if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
#endif
};

server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
server_method_type_item: T_SSLV3
{
#ifdef HAVE_LIBCRYPTO
if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
#endif
} | T_TLSV1
{
#ifdef HAVE_LIBCRYPTO
if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
#endif
};

serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
{
#ifdef HAVE_LIBCRYPTO
@@ -638,6 +606,48 @@ serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
#endif
};

serverinfo_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';'
{
#ifdef HAVE_LIBCRYPTO
if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
{
if ((ServerInfo.message_digest_algorithm = EVP_get_digestbyname(yylval.string)) == NULL)
{
ServerInfo.message_digest_algorithm = EVP_sha256();
conf_error_report("Ignoring serverinfo::ssl_message_digest_algorithm -- unknown message digest algorithm");
}
}
#endif
}

serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';'
{
#ifdef HAVE_LIBCRYPTO
#if OPENSSL_VERSION_NUMBER >= 0x1000005FL && !defined(OPENSSL_NO_ECDH)
int nid = 0;
EC_KEY *key = NULL;

if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
{
if ((nid = OBJ_sn2nid(yylval.string)) == 0)
{
conf_error_report("Ignoring serverinfo::serverinfo_ssl_dh_elliptic_curve -- unknown curve name");
break;
}

if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
{
conf_error_report("Ignoring serverinfo::serverinfo_ssl_dh_elliptic_curve -- could not create curve");
break;
}

SSL_CTX_set_tmp_ecdh(ServerInfo.server_ctx, key);
EC_KEY_free(key);
}
#endif
#endif
};

serverinfo_name: NAME '=' QSTRING ';'
{
/* this isn't rehashable */
@@ -684,7 +694,7 @@ serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
char *p;

if ((p = strchr(yylval.string, ' ')))
p = '\0';
*p = '\0';

MyFree(ServerInfo.network_name);
ServerInfo.network_name = xstrdup(yylval.string);
@@ -1221,10 +1231,6 @@ oper_umodes_item: T_BOTS
{
if (conf_parser_ctx.pass == 2)
block_state.modes.value |= UMODE_EXTERNAL;
} | T_OPERWALL
{
if (conf_parser_ctx.pass == 2)
block_state.modes.value |= UMODE_OPERWALL;
} | T_SERVNOTICE
{
if (conf_parser_ctx.pass == 2)
@@ -1293,7 +1299,7 @@ oper_flags_item: KILL ':' REMOTE
} | KLINE
{
if (conf_parser_ctx.pass == 2)
block_state.port.value |= OPER_FLAG_K;
block_state.port.value |= OPER_FLAG_KLINE;
} | UNKLINE
{
if (conf_parser_ctx.pass == 2)
@@ -1334,10 +1340,6 @@ oper_flags_item: KILL ':' REMOTE
{
if (conf_parser_ctx.pass == 2)
block_state.port.value |= OPER_FLAG_ADMIN;
} | T_OPERWALL
{
if (conf_parser_ctx.pass == 2)
block_state.port.value |= OPER_FLAG_OPERWALL;
} | T_GLOBOPS
{
if (conf_parser_ctx.pass == 2)
@@ -1405,6 +1407,7 @@ class_entry: CLASS
class->max_ident = block_state.max_ident.value;
class->max_sendq = block_state.max_sendq.value;
class->max_recvq = block_state.max_recvq.value;
class->max_channels = block_state.max_channels.value;

if (block_state.min_idle.value > block_state.max_idle.value)
{
@@ -1437,6 +1440,7 @@ class_item: class_name |
class_number_per_cidr |
class_number_per_ip |
class_connectfreq |
class_max_channels |
class_max_number |
class_max_global |
class_max_local |
@@ -1471,6 +1475,12 @@ class_connectfreq: CONNECTFREQ '=' timespec ';'
block_state.con_freq.value = $3;
};

class_max_channels: MAX_CHANNELS '=' NUMBER ';'
{
if (conf_parser_ctx.pass == 1)
block_state.max_channels.value = $3;
};

class_max_number: MAX_NUMBER '=' NUMBER ';'
{
if (conf_parser_ctx.pass == 1)
@@ -2481,6 +2491,7 @@ general_item: general_hide_spoof_ips |
general_default_floodcount |
general_min_nonwildcard |
general_min_nonwildcard_simple |
general_throttle_count |
general_throttle_time |
general_havent_read_conf |
general_ping_cookie |
@@ -2738,6 +2749,11 @@ general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
ConfigFileEntry.disable_auth = yylval.number;
};

general_throttle_count: THROTTLE_COUNT '=' NUMBER ';'
{
ConfigFileEntry.throttle_count = $3;
};

general_throttle_time: THROTTLE_TIME '=' timespec ';'
{
ConfigFileEntry.throttle_time = $3;
@@ -2791,9 +2807,6 @@ umode_oitem: T_BOTS
} | T_EXTERNAL
{
ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
} | T_OPERWALL
{
ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
} | T_SERVNOTICE
{
ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
@@ -2862,9 +2875,6 @@ umode_item: T_BOTS
} | T_EXTERNAL
{
ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
} | T_OPERWALL
{
ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
} | T_SERVNOTICE
{
ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
@@ -2915,10 +2925,12 @@ channel_entry: CHANNEL

channel_items: channel_items channel_item | channel_item;
channel_item: channel_max_bans |
channel_knock_delay |
channel_invite_client_count |
channel_invite_client_time |
channel_knock_client_count |
channel_knock_client_time |
channel_knock_delay_channel |
channel_max_chans_per_user |
channel_max_chans_per_oper |
channel_max_channels |
channel_default_split_user_count |
channel_default_split_server_count |
channel_no_create_on_split |
@@ -2933,24 +2945,34 @@ channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
ConfigChannel.disable_fake_channels = yylval.number;
};

channel_knock_delay: KNOCK_DELAY '=' timespec ';'
channel_invite_client_count: INVITE_CLIENT_COUNT '=' NUMBER ';'
{
ConfigChannel.knock_delay = $3;
ConfigChannel.invite_client_count = $3;
};

channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
channel_invite_client_time: INVITE_CLIENT_TIME '=' timespec ';'
{
ConfigChannel.knock_delay_channel = $3;
ConfigChannel.invite_client_time = $3;
};

channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';'
{
ConfigChannel.max_chans_per_user = $3;
ConfigChannel.knock_client_count = $3;
};

channel_knock_client_time: KNOCK_CLIENT_TIME '=' timespec ';'
{
ConfigChannel.knock_client_time = $3;
};

channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
{
ConfigChannel.knock_delay_channel = $3;
};

channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
channel_max_channels: MAX_CHANNELS '=' NUMBER ';'
{
ConfigChannel.max_chans_per_oper = $3;
ConfigChannel.max_channels = $3;
};

channel_max_bans: MAX_BANS '=' NUMBER ';'
@@ -3044,7 +3066,8 @@ serverhide_links_delay: LINKS_DELAY '=' timespec ';'
{
if (($3 > 0) && ConfigServerHide.links_disabled == 1)
{
eventAddIsh("write_links_file", write_links_file, NULL, $3);
event_write_links_file.when = $3;
event_addish(&event_write_links_file, NULL);
ConfigServerHide.links_disabled = 0;
}

@@ -43,8 +43,6 @@ dbuf_alloc(void)
{
struct dbuf_block *block = mp_pool_get(dbuf_pool);

memset(block, 0, sizeof(*block));

++block->refs;
return block;
}
@@ -1,28 +1,8 @@
/*
* ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
* event.c: Event functions.
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
*
* Copyright (c) 1998-2000 Regents of the University of California
* Copyright (c) 2000-2014 ircd-hybrid development team
*
* Code borrowed from the squid web cache by Adrian Chadd.
* Original header:
*
* DEBUG: section 41 Event Processing
* AUTHOR: Henrik Nordstrom
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
* ----------------------------------------------------------
*
* Squid is the result of efforts by numerous individuals from the
* Internet community. Development is led by Duane Wessels of the
* National Laboratory for Applied Network Research and funded by the
* National Science Foundation. Squid is Copyrighted (C) 1998 by
* the Regents of the University of California. Please see the
* COPYRIGHT file for full details. Squid incorporates software
* developed and/or copyrighted by other sources. Please see the
* CREDITS file for full details.
*
* 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
* the Free Software Foundation; either version 2 of the License, or
@@ -37,16 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* $Id$
*/

/*
* How it's used:
*
* Should be pretty self-explanatory. Events are added to the static
* array event_table with a frequency time telling eventRun how often
* to execute it.
/*! \file event.c
* \brief Timer based event execution
* \version $Id$
*/

#include "stdinc.h"
@@ -55,165 +30,102 @@
#include "event.h"
#include "client.h"
#include "send.h"
#include "memory.h"
#include "log.h"
#include "numeric.h"
#include "rng_mt.h"

static dlink_list events;

static const char *last_event_ran = NULL;
static struct ev_entry event_table[MAX_EVENTS];
static time_t event_time_min = -1;


/*
* int eventFind(EVH *func, void *arg)
*
* Input: Event function and the argument passed to it
* Output: Index to the slow in the event_table
* Side Effects: None
*/
static int
eventFind(EVH *func, void *arg)
void
event_add(struct event *ev, void *data)
{
for (unsigned int i = 0; i < MAX_EVENTS; ++i)
if ((event_table[i].func == func) &&
(event_table[i].arg == arg) &&
event_table[i].active)
return i;
dlink_node *node;

return -1;
}
event_delete(ev);

/*
* void eventAdd(const char *name, EVH *func, void *arg, time_t when)
*
* Input: Name of event, function to call, arguments to pass, and frequency
* of the event.
* Output: None
* Side Effects: Adds the event to the event list.
*/
void
eventAdd(const char *name, EVH *func, void *arg, time_t when)
{
/* find first inactive index, or use next index */
for (unsigned int i = 0; i < MAX_EVENTS; ++i)
{
if (event_table[i].active == 0)
{
event_table[i].func = func;
event_table[i].name = name;
event_table[i].arg = arg;
event_table[i].when = CurrentTime + when;
event_table[i].frequency = when;
event_table[i].active = 1;
ev->data = data;
ev->next = CurrentTime + ev->when;
ev->enabled = 1;

if ((event_table[i].when < event_time_min) || (event_time_min == -1))
event_time_min = event_table[i].when;
DLINK_FOREACH(node, events.head)
{
struct event *e = node->data;

if (e->next > ev->next)
{
dlinkAddBefore(node, ev, &ev->node, &events);
return;
}
}

dlinkAddTail(ev, &ev->node, &events);
}

/*
* void eventDelete(EVH *func, void *arg)
*
* Input: Function handler, argument that was passed.
* Output: None
* Side Effects: Removes the event from the event list
*/
void
eventDelete(EVH *func, void *arg)
event_addish(struct event *ev, void *data)
{
int i = eventFind(func, arg);
if (ev->when >= 3)
{
const time_t two_third = (2 * ev->when) / 3;

if (i == -1)
return;
ev->when = two_third + ((genrand_int32() % 1000) * two_third) / 1000;
}

event_table[i].name = NULL;
event_table[i].func = NULL;
event_table[i].arg = NULL;
event_table[i].active = 0;
event_add(ev, data);
}

/*
* void eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_isa)
*
* Input: Name of event, function to call, arguments to pass, and frequency
* of the event.
* Output: None
* Side Effects: Adds the event to the event list within +- 1/3 of the
* specified frequency.
*/
void
eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_ish)
event_delete(struct event *ev)
{
if (delta_ish >= 3)
{
const time_t two_third = (2 * delta_ish) / 3;
delta_ish = two_third + ((genrand_int32() % 1000) * two_third) / 1000;
/*
* XXX I hate the above magic, I don't even know if its right.
* Grr. -- adrian
*/
}
if (!ev->enabled)
return;

eventAdd(name, func, arg, delta_ish);
dlinkDelete(&ev->node, &events);
ev->enabled = 0;
}

/*
* void eventRun(void)
*
* Input: None
* Output: None
* Side Effects: Runs pending events in the event list
*/
void
eventRun(void)
event_run(void)
{
for (unsigned int i = 0; i < MAX_EVENTS; ++i)
static time_t last = 0;
unsigned int len = 0;

if (last == CurrentTime)
return;
last = CurrentTime;

len = dlink_list_length(&events);
while (len-- && dlink_list_length(&events))
{
if (event_table[i].active && (event_table[i].when <= CurrentTime))
{
last_event_ran = event_table[i].name;
event_table[i].func(event_table[i].arg);
event_table[i].when = CurrentTime + event_table[i].frequency;
event_time_min = -1;
}
}
}
struct event *e = events.head->data;

/*
* time_t eventNextTime(void)
*
* Input: None
* Output: Specifies the next time eventRun() should be run
* Side Effects: None
*/
time_t
eventNextTime(void)
{
if (event_time_min == -1)
for (unsigned int i = 0; i < MAX_EVENTS; ++i)
if (event_table[i].active && ((event_table[i].when < event_time_min) || (event_time_min == -1)))
event_time_min = event_table[i].when;
if (e->next > CurrentTime)
break;

event_delete(e);

return event_time_min;
e->handler(e->data);

if (!e->oneshot)
event_add(e, e->data);
}
}

/*
* void eventInit(void)
*
* Input: None
* Output: None
* Side Effects: Initializes the event system.
* void set_back_events(time_t by)
* Input: Time to set back events by.
* Output: None.
* Side-effects: Sets back all events by "by" seconds.
*/
void
eventInit(void)
set_back_events(time_t by)
{
last_event_ran = NULL;
memset(event_table, 0, sizeof(event_table));
dlink_node *node;

DLINK_FOREACH(node, events.head)
{
struct event *ev = node->data;
ev->next -= by;
}
}

/*
@@ -226,44 +138,21 @@ eventInit(void)
void
show_events(struct Client *source_p)
{
if (last_event_ran)
{
sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E :Last event to run: %s",
last_event_ran);
sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E : ");
}
const dlink_node *node;

sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E :Operation Next Execution");
sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E :-------------------------------------------");

for (unsigned i = 0; i < MAX_EVENTS; ++i)
if (event_table[i].active)
sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E :%-28s %-4d seconds",
event_table[i].name,
(int)(event_table[i].when - CurrentTime));
}

/*
* void set_back_events(time_t by)
* Input: Time to set back events by.
* Output: None.
* Side-effects: Sets back all events by "by" seconds.
*/
void
set_back_events(time_t by)
{
event_time_min = -1;

for (unsigned int i = 0; i < MAX_EVENTS; ++i)
DLINK_FOREACH(node, events.head)
{
if (event_table[i].when > by)
event_table[i].when -= by;
else
event_table[i].when = 0;
const struct event *ev = node->data;

sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
"E :%-28s %-4d seconds",
ev->name,
(int)(ev->next - CurrentTime));
}
}

@@ -546,7 +546,6 @@ find_or_add_userhost(const char *host)

userhost = mp_pool_get(userhost_pool);

memset(userhost, 0, sizeof(*userhost));
strlcpy(userhost->host, host, sizeof(userhost->host));
hash_add_userhost(userhost);

@@ -567,7 +566,7 @@ add_user_host(const char *user, const char *host, int global)
dlink_node *ptr;
struct UserHost *found_userhost;
struct NameHost *nameh;
int hasident = 1;
unsigned int hasident = 1;

if (*user == '~')
{
@@ -598,7 +597,7 @@ add_user_host(const char *user, const char *host, int global)
}

nameh = mp_pool_get(namehost_pool);
memset(nameh, 0, sizeof(*nameh));

strlcpy(nameh->name, user, sizeof(nameh->name));

nameh->gcount = 1;

This file was deleted.

@@ -326,10 +326,12 @@ mask_addr(struct irc_ssaddr *ip, int bits)
if (ip->ss.ss_family != AF_INET6)
#endif
{
uint32_t tmp = 0;
v4_base_ip = (struct sockaddr_in *)ip;

mask = ~((1 << (32 - bits)) - 1);
v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
tmp = ntohl(v4_base_ip->sin_addr.s_addr);
v4_base_ip->sin_addr.s_addr = htonl(tmp & mask);
}
#ifdef IPV6
else
@@ -53,7 +53,6 @@
#include "memory.h"
#include "mempool.h"
#include "ircd_getopt.h"
#include "supported.h"
#include "watch.h"
#include "conf_db.h"
#include "conf_class.h"
@@ -63,10 +62,6 @@
GeoIP *geoip_ctx;
#endif

/* /quote set variables */
struct SetOptions GlobalSetOptions;
struct Counter Count;
struct ServerState_t server_state;
struct ServerStatistics ServerStats;
struct timeval SystemTime;
struct Client me; /* That's me */
@@ -83,23 +78,52 @@ int doremotd = 0;
/* Set to zero because it should be initialized later using
* initialize_server_capabs
*/
int default_server_capabs = 0;
unsigned int default_server_capabs;
unsigned int splitmode;
unsigned int splitchecking;
unsigned int split_users;
unsigned int split_servers;

/* Do klines the same way hybrid-6 did them, i.e. at the
* top of the next io_loop instead of in the same loop as
* the klines are being applied.
*
* This should fix strange CPU starvation as very indirectly reported.
* (Why do you people not email bug reports? WHY? WHY?)
*
* - Dianora
*/
static struct event event_cleanup_glines =
{
.name = "cleanup_glines",
.handler = cleanup_glines,
.when = CLEANUP_GLINES_TIME
};

static struct event event_cleanup_tklines =
{
.name = "cleanup_tklines",
.handler = cleanup_tklines,
.when = CLEANUP_TKLINES_TIME
};

static struct event event_try_connections =
{
.name = "try_connections",
.handler = try_connections,
.when = STARTUP_CONNECTIONS_TIME
};

static struct event event_comm_checktimeouts =
{
.name = "comm_checktimeouts",
.handler = comm_checktimeouts,
.when = 1
};

static struct event event_save_all_databases =
{
.name = "save_all_databases",
.handler = save_all_databases,
.when = DATABASE_UPDATE_TIMEOUT
};

int rehashed_klines = 0;
struct event event_write_links_file =
{
.name = "write_links_file",
.handler = write_links_file,
};


/*
@@ -196,32 +220,15 @@ io_loop(void)
{
while (1)
{
/*
* Maybe we want a flags word?
* ie. if (REHASHED_KLINES(global_flags))
* SET_REHASHED_KLINES(global_flags)
* CLEAR_REHASHED_KLINES(global_flags)
*
* - Dianora
*/
if (rehashed_klines)
{
check_conf_klines();
rehashed_klines = 0;
}

if (listing_client_list.head)
{
dlink_node *ptr = NULL, *ptr_next = NULL;
DLINK_FOREACH_SAFE(ptr, ptr_next, listing_client_list.head)
safe_list_channels(ptr->data, 0);
}

/* Run pending events, then get the number of seconds to the next
* event
*/
while (eventNextTime() <= CurrentTime)
eventRun();
/* Run pending events */
event_run();

comm_select();
exit_aborted_clients();
@@ -296,9 +303,7 @@ initialize_server_capabs(void)
add_capability("CLUSTER", CAP_CLUSTER, 1);
add_capability("SVS", CAP_SVS, 1);
add_capability("CHW", CAP_CHW, 1);
#ifdef HALFOPS
add_capability("HOPS", CAP_HOPS, 1);
#endif
}

/* write_pidfile()
@@ -422,30 +427,42 @@ ssl_init(void)

if ((ServerInfo.server_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
{
const char *s;
const char *s = ERR_lib_error_string(ERR_get_error());

fprintf(stderr, "ERROR: Could not initialize the SSL Server context -- %s\n",
s = ERR_lib_error_string(ERR_get_error()));
fprintf(stderr, "ERROR: Could not initialize the SSL Server context -- %s\n", s);
ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the SSL Server context -- %s\n", s);
}

SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL);
SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_set_verify(ServerInfo.server_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
always_accept_verify_cb);
SSL_CTX_set_session_id_context(ServerInfo.server_ctx, session_id, sizeof(session_id) - 1);

#if OPENSSL_VERSION_NUMBER >= 0x1000005FL && !defined(OPENSSL_NO_ECDH)
{
EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

if (key)
{
SSL_CTX_set_tmp_ecdh(ServerInfo.server_ctx, key);
EC_KEY_free(key);
}
}

SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_SINGLE_ECDH_USE);
#endif

if ((ServerInfo.client_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
{
const char *s;
const char *s = ERR_lib_error_string(ERR_get_error());

fprintf(stderr, "ERROR: Could not initialize the SSL Client context -- %s\n",
s = ERR_lib_error_string(ERR_get_error()));
fprintf(stderr, "ERROR: Could not initialize the SSL Client context -- %s\n", s);
ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the SSL Client context -- %s\n", s);
}

SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL);
SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_set_verify(ServerInfo.client_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
always_accept_verify_cb);
#endif /* HAVE_LIBCRYPTO */
@@ -473,6 +490,7 @@ main(int argc, char *argv[])
me.localClient = &meLocalUser;
dlinkAdd(&me, &me.node, &global_client_list); /* Pointer to beginning
of Client list */
ConfigLoggingEntry.use_logging = 1;
ConfigFileEntry.dpath = DPATH;
ConfigFileEntry.spath = SPATH;
ConfigFileEntry.mpath = MPATH;
@@ -512,9 +530,6 @@ main(int argc, char *argv[])

setup_signals();

/* Init the event subsystem */
eventInit();

/* We need this to initialise the fd array before anything else */
fdlist_init();
log_set_file(LOG_TYPE_IRCD, 0, logFileName);
@@ -622,25 +637,28 @@ main(int argc, char *argv[])

ilog(LOG_TYPE_IRCD, "Server Ready");

eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME);
eventAddIsh("cleanup_tklines", cleanup_tklines, NULL, CLEANUP_TKLINES_TIME);
event_addish(&event_cleanup_glines, NULL);
event_addish(&event_cleanup_tklines, NULL);

/* We want try_connections to be called as soon as possible now! -- adrian */
/* No, 'cause after a restart it would cause all sorts of nick collides */
eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
event_addish(&event_try_connections, NULL);

/* Setup the timeout check. I'll shift it later :) -- adrian */
eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);
event_addish(&event_comm_checktimeouts, NULL);

eventAddIsh("save_all_databases", save_all_databases, NULL, DATABASE_UPDATE_TIMEOUT);
event_addish(&event_save_all_databases, NULL);

if (ConfigServerHide.links_delay > 0)
eventAddIsh("write_links_file", write_links_file, NULL, ConfigServerHide.links_delay);
{
event_write_links_file.when = ConfigServerHide.links_delay;
event_addish(&event_write_links_file, NULL);
}
else
ConfigServerHide.links_disabled = 1;

if (splitmode)
eventAddIsh("check_splitmode", check_splitmode, NULL, 60);
event_addish(&splitmode_event, NULL);

io_loop();
return 0;
@@ -55,7 +55,6 @@ make_dlink_node(void)
{
dlink_node *ptr = mp_pool_get(dnode_pool);

memset(ptr, 0, sizeof(*ptr));
return ptr;
}

@@ -354,7 +354,7 @@ close_listeners(void)
close_listener(ptr->data);
}

#define TOOFAST_WARNING "ERROR :Trying to reconnect too fast.\r\n"
#define TOOFAST_WARNING "ERROR :Your host is trying to (re)connect too fast -- throttled.\r\n"
#define DLINE_WARNING "ERROR :You have been D-lined.\r\n"

static void
@@ -42,7 +42,7 @@ match(const char *mask, const char *name)
{
const char *m = mask, *n = name;
const char *m_tmp = mask, *n_tmp = name;
int star = 0;
unsigned int star = 0;

while (1)
{
@@ -135,7 +135,7 @@ match(const char *mask, const char *name)
char *
collapse(char *mask)
{
int star = 0;
unsigned int star = 0;
char *m = mask;
char *b = NULL;

@@ -235,7 +235,14 @@ static mp_pool_t *mp_allocated_pools = NULL;
void
mp_pool_init(void)
{
eventAdd("mp_pool_garbage_collect", &mp_pool_garbage_collect, NULL, 119);
static struct event event_mp_gc =
{
.name = "mp_pool_garbage_collect",
.handler = mp_pool_garbage_collect,
.when = 187
};

event_add(&event_mp_gc, NULL);
}

/** Helper: Allocate and return a new memory chunk for <b>pool</b>. Does not
@@ -276,6 +283,7 @@ mp_pool_get(mp_pool_t *pool)
{
mp_chunk_t *chunk;
mp_allocated_t *allocated;
void *ptr = NULL;

if (pool->used_chunks)
{
@@ -364,8 +372,12 @@ mp_pool_get(mp_pool_t *pool)
chunk->next->prev = chunk;
pool->full_chunks = chunk;
}

/* And return the memory portion of the mp_allocated_t. */
return A2M(allocated);
ptr = A2M(allocated);
memset(ptr, 0, pool->item_size);

return ptr;
}

/** Return an allocated memory item to its memory pool. */
@@ -489,6 +501,7 @@ mp_pool_new(size_t item_size, size_t chunk_capacity)
assert(new_chunk_cap < INT_MAX);
pool->new_chunk_capacity = (int)new_chunk_cap;

pool->item_size = item_size;
pool->item_alloc_size = alloc_size;

pool->next = mp_allocated_pools;
@@ -34,11 +34,7 @@ static const char *const replies[] =
/* 001 RPL_WELCOME */ ":Welcome to the %s Internet Relay Chat Network %s",
/* 002 RPL_YOURHOST */ ":Your host is %s, running version %s",
/* 003 RPL_CREATED */ ":This server was created %s",
#ifdef HALFOPS
/* 004 RPL_MYINFO */ "%s %s %s bciklmnoprstveIMORS bkloveIh",
#else
/* 004 RPL_MYINFO */ "%s %s %s bciklmnoprstveIMORS bkloveI",
#endif
/* 005 RPL_ISUPPORT */ "%s :are supported by this server",
/* 006 */ NULL,
/* 007 */ NULL,
@@ -369,9 +365,9 @@ static const char *const replies[] =
/* 332 RPL_TOPIC */ "%s :%s",
/* 333 RPL_TOPICWHOTIME */ "%s %s %lu",
/* 334 */ NULL,
/* 335 */ NULL,
/* 336 */ NULL,
/* 337 RPL_WHOISTEXT */ "%s :%s",
/* 335 RPL_WHOISTEXT */ "%s :%s",
/* 336 RPL_INVITELIST */ ":%s",
/* 337 RPL_ENDOFINVITELIST */ ":End of /INVITE list.",
/* 338 RPL_WHOISACTUALLY */ "%s %s :actually using host",
/* 339 */ NULL,
/* 340 */ NULL,
@@ -749,7 +745,7 @@ static const char *const replies[] =
/* 712 ERR_TOOMANYKNOCK */ "%s :Too many KNOCKs (%s).",
/* 713 ERR_CHANOPEN */ "%s :Channel is open.",
/* 714 ERR_KNOCKONCHAN */ "%s :You are already on that channel.",
/* 715 */ NULL,
/* 715 ERR_TOOMANYINVITE */ "%s :Too many INVITEs (%s).",
/* 716 RPL_TARGUMODEG */ "%s :is in %s mode (%s)",
/* 717 RPL_TARGNOTIFY */ "%s :has been informed that you messaged them.",
/* 718 RPL_UMODEGMSG */ "%s :is messaging you, and you are umode %s.",
@@ -100,7 +100,7 @@ struct MessageTree

static struct MessageTree msg_tree;

static int cancel_clients(struct Client *, struct Client *, char *);
static void cancel_clients(struct Client *, struct Client *, char *);
static void remove_unknown(struct Client *, char *, char *);
static void handle_numeric(unsigned int, struct Client *, int, char *[]);
static void handle_command(struct Message *, struct Client *, unsigned int, char *[]);
@@ -440,8 +440,6 @@ msg_tree_parse(const char *cmd)
* inputs - pointer to struct Message
* output - none
* side effects - load this one command name
* msg->count msg->bytes is modified in place, in
* modules address space. Might not want to do that...
*/
void
mod_add_cmd(struct Message *msg)
@@ -453,7 +451,6 @@ mod_add_cmd(struct Message *msg)
return;

add_msg_element(&msg_tree, msg, msg->cmd);
msg->count = msg->rcount = msg->bytes = 0;
}

/* mod_del_cmd()
@@ -521,32 +518,9 @@ report_messages(struct Client *source_p)
* output -
* side effects -
*/
static int
static void
cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd)
{
/*
* Kill all possible points that are causing confusion here,
* I'm not sure I've got this all right...
* - avalon
*
* Knowing avalon, probably not.
*/

/*
* With TS, fake prefixes are a common thing, during the
* connect burst when there's a nick collision, and they
* must be ignored rather than killed because one of the
* two is surviving.. so we don't bother sending them to
* all ops everytime, as this could send 'private' stuff
* from lagged clients. we do send the ones that cause
* servers to be dropped though, as well as the ones from
* non-TS servers -orabidoo
*/
/*
* Incorrect prefix for a server from some connection. If it is a
* client trying to be annoying, just QUIT them, if it is a server
* then the same deal.
*/
if (IsServer(source_p) || IsMe(source_p))
{
sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
@@ -560,21 +534,9 @@ cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd)
sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
"Not dropping server %s (%s) for Fake Direction",
client_p->name, source_p->name);
return -1;
/* return exit_client(client_p, client_p, &me, "Fake Direction");*/
return;
}

/*
* Ok, someone is trying to impose as a client and things are
* confused. If we got the wrong prefix from a server, send out a
* kill, else just exit the lame client.
*/
/*
* If the fake prefix is coming from a TS server, discard it
* silently -orabidoo
*
* all servers must be TS these days --is
*/
sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
"Message for %s[%s@%s!%s] from %s (TS, ignored)",
source_p->name, source_p->username, source_p->host,
@@ -583,7 +545,6 @@ cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd)
"Message for %s[%s@%s!%s] from %s (TS, ignored)",
source_p->name, source_p->username, source_p->host,
source_p->from->name, get_client_name(client_p, MASK_IP));
return 0;
}

/* remove_unknown()
@@ -70,8 +70,6 @@
static PF res_readreply;

#define MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
#define RES_MAXALIASES 35 /* maximum aliases allowed */
#define RES_MAXADDRS 35 /* maximum addresses allowed */
#define AR_TTL 600 /* TTL in seconds for dns cache entries */

/* RFC 1104/1105 wasn't very helpful about what these fields
@@ -256,7 +254,6 @@ start_resolver(void)

/* At the moment, the resolver FD data is global .. */
comm_setselect(&ResolverFileDescriptor, COMM_SELECT_READ, res_readreply, NULL, 0);
eventAdd("timeout_resolver", timeout_resolver, NULL, 1);
}
}

@@ -266,9 +263,18 @@ start_resolver(void)
void
init_resolver(void)
{
static struct event event_timeout_resolver =
{
.name = "timeout_resolver",
.handler = timeout_resolver,
.when = 1
};

dns_pool = mp_pool_new(sizeof(struct reslist), MP_CHUNK_SIZE_DNS);
memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
start_resolver();

event_add(&event_timeout_resolver, NULL);
}

/*
@@ -278,7 +284,6 @@ void
restart_resolver(void)
{
fd_close(&ResolverFileDescriptor);
eventDelete(timeout_resolver, NULL);
start_resolver();
}

@@ -304,7 +309,6 @@ make_request(dns_callback_fnc callback, void *ctx)
{
struct reslist *request = mp_pool_get(dns_pool);

memset(request, 0, sizeof(*request));
request->sentat = CurrentTime;
request->retries = 2;
request->resend = 1;

Large diffs are not rendered by default.

@@ -1,12 +1,12 @@
/*
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -19,8 +19,8 @@
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -46,7 +46,7 @@
#include "stdinc.h"
#include "rng_mt.h"

/* Period parameters */
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfU /* constant vector a */
@@ -119,15 +119,15 @@ init_by_array(uint32_t init_key[], int key_length)
}
}

mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
}

/* generates a random number on [0,0xffffffff]-interval */
uint32_t
genrand_int32(void)
{
uint32_t y;
static uint32_t mag01[2]={ 0x0U, MATRIX_A };
static uint32_t mag01[2] = { 0x0U, MATRIX_A };
/* mag01[x] = x * MATRIX_A for x=0,1 */

if (mti >= N)
@@ -154,7 +154,7 @@ genrand_int32(void)

mti = 0;
}

y = mt[mti++];

/* Tempering */
@@ -52,19 +52,18 @@ report_crypto_errors(void)
ilog(LOG_TYPE_IRCD, "SSL error: %s", ERR_error_string(e, 0));
}

static void
binary_to_hex(unsigned char *bin, char *hex, unsigned int length)
void
binary_to_hex(const unsigned char *bin, char *hex, unsigned int length)
{
static const char trans[] = "0123456789ABCDEF";
unsigned int i = 0;

for (; i < length; ++i)
for (const unsigned char *end = bin + length; bin < end; ++bin)
{
hex[(i << 1) ] = trans[bin[i] >> 4];
hex[(i << 1) + 1] = trans[bin[i] & 0xf];
*hex++ = trans[*bin >> 4];
*hex++ = trans[*bin & 0xf];
}

hex[i << 1] = '\0';
*hex = '\0';
}

int
@@ -25,6 +25,9 @@
*/

#include "stdinc.h"
#ifdef HAVE_LIBCRYPTO
#include "rsa.h"
#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
@@ -278,10 +281,9 @@ ssl_handshake(int fd, struct Client *client_p)
{
unsigned int n = 0;

if (X509_digest(cert, EVP_sha256(), md, &n))
if (X509_digest(cert, ServerInfo.message_digest_algorithm, md, &n))
{
for (unsigned int i = 0; i < n; ++i)
snprintf(buf + 2 * i, 3, "%02X", md[i]);
binary_to_hex(md, buf, n);
client_p->certfp = xstrdup(buf);
}
}
@@ -28,69 +28,13 @@
#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_EPOLL
#include "fdlist.h"
#include "ircd.h"
#include "memory.h"
#include "s_bsd.h"
#include "log.h"
#include <sys/epoll.h>
#include <sys/syscall.h>

static fde_t efd;

/* Thanks to ircu for the following ifdefs. */

/* The GNU C library may have a valid header but stub implementations
* of the epoll system calls. If so, provide our own. */
#if defined(__stub_epoll_create) || defined(__stub___epoll_create) || defined(EPOLL_NEED_BODY)

/* Oh, did we mention that some glibc releases do not even define the
* syscall numbers? */
#if !defined(__NR_epoll_create)
#if defined(__ia64__)
#define __NR_epoll_create 1243
#define __NR_epoll_ctl 1244
#define __NR_epoll_wait 1245
#elif defined(__x86_64__)
#define __NR_epoll_create 214
#define __NR_epoll_ctl 233
#define __NR_epoll_wait 232
#elif defined(__sparc64__) || defined(__sparc__)
#define __NR_epoll_create 193
#define __NR_epoll_ctl 194
#define __NR_epoll_wait 195
#elif defined(__s390__) || defined(__m68k__)
#define __NR_epoll_create 249
#define __NR_epoll_ctl 250
#define __NR_epoll_wait 251
#elif defined(__ppc64__) || defined(__ppc__)
#define __NR_epoll_create 236
#define __NR_epoll_ctl 237
#define __NR_epoll_wait 238
#elif defined(__parisc__) || defined(__arm26__) || defined(__arm__)
#define __NR_epoll_create 224
#define __NR_epoll_ctl 225
#define __NR_epoll_wait 226
#elif defined(__alpha__)
#define __NR_epoll_create 407
#define __NR_epoll_ctl 408
#define __NR_epoll_wait 409
#elif defined(__sh64__)
#define __NR_epoll_create 282
#define __NR_epoll_ctl 283
#define __NR_epoll_wait 284
#elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || defined(__h8300__) || defined(__frv__)
#define __NR_epoll_create 254
#define __NR_epoll_ctl 255
#define __NR_epoll_wait 256
#else /* cpu types */
#error No system call numbers defined for epoll family.
#endif /* cpu types */
#endif /* !defined(__NR_epoll_create) */

_syscall1(int, epoll_create, int, size)
_syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, event)
_syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents, int, maxevents, int, timeout)

#endif /* epoll_create defined as stub */

/*
* init_netio
@@ -29,29 +29,16 @@
#include <sys/event.h>
#include "fdlist.h"
#include "ircd.h"
#include "memory.h"
#include "s_bsd.h"
#include "log.h"

#define KE_LENGTH 128

/* jlemon goofed up and didn't add EV_SET until fbsd 4.3 */

#ifndef EV_SET
#define EV_SET(kevp, a, b, c, d, e, f) do { \
(kevp)->ident = (a); \
(kevp)->filter = (b); \
(kevp)->flags = (c); \
(kevp)->fflags = (d); \
(kevp)->data = (e); \
(kevp)->udata = (f); \
} while(0)
#endif

static fde_t kqfd;
static struct kevent kq_fdlist[KE_LENGTH]; /* kevent buffer */
static int kqoff; /* offset into the buffer */


/*
* init_netio
*
@@ -28,7 +28,6 @@
#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_SELECT
#include "list.h"
#include "fdlist.h"
#include "hook.h"
#include "ircd.h"
#include "s_bsd.h"
#include "log.h"
@@ -410,10 +410,10 @@ sendto_channel_butone(struct Client *one, struct Client *from,

local_buf = dbuf_alloc(), remote_buf = dbuf_alloc();

if (IsServer(from))
dbuf_put_fmt(local_buf, ":%s ", from->name);
else
if (IsClient(from))
dbuf_put_fmt(local_buf, ":%s!%s@%s ", from->name, from->username, from->host);
else
dbuf_put_fmt(local_buf, ":%s ", from->name);

dbuf_put_fmt(remote_buf, ":%s ", from->id);

@@ -542,12 +542,12 @@ sendto_common_channels_local(struct Client *user, int touser, unsigned int cap,
{
chptr = ((struct Membership *)cptr->data)->chptr;

DLINK_FOREACH(uptr, chptr->members.head)
DLINK_FOREACH(uptr, chptr->locmembers.head)
{
ms = uptr->data;
target_p = ms->client_p;

if (!MyConnect(target_p) || target_p == user || IsDefunct(target_p) ||
if (target_p == user || IsDefunct(target_p) ||
target_p->localClient->serial == current_serial)
continue;

@@ -591,15 +591,15 @@ sendto_channel_local(unsigned int type, int nodeaf, struct Channel *chptr,
send_format(buffer, pattern, args);
va_end(args);

DLINK_FOREACH(ptr, chptr->members.head)
DLINK_FOREACH(ptr, chptr->locmembers.head)
{
struct Membership *ms = ptr->data;
struct Client *target_p = ms->client_p;

if (type && (ms->flags & type) == 0)
continue;

if (!MyConnect(target_p) || IsDefunct(target_p) ||
if (IsDefunct(target_p) ||
(nodeaf && HasUMode(target_p, UMODE_DEAF)))
continue;

@@ -635,15 +635,15 @@ sendto_channel_local_butone(struct Client *one, unsigned int type, unsigned int
send_format(buffer, pattern, args);
va_end(args);

DLINK_FOREACH(ptr, chptr->members.head)
DLINK_FOREACH(ptr, chptr->locmembers.head)
{
struct Membership *ms = ptr->data;
struct Client *target_p = ms->client_p;

if (type && (ms->flags & type) == 0)
continue;

if (!MyConnect(target_p) || (one && target_p == one->from))
if (one && target_p == one->from)
continue;

if (IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF))
@@ -772,19 +772,19 @@ sendto_match_servs(struct Client *source_p, const char *mask, unsigned int cap,
const char *pattern, ...)
{
va_list args;
dlink_node *ptr = NULL;
struct dbuf_block *buff_suid;
dlink_node *ptr = NULL, *ptr_next = NULL;
struct dbuf_block *buffer;

buff_suid = dbuf_alloc();
buffer = dbuf_alloc();

dbuf_put_fmt(buffer, ":%s ", source_p->id);
va_start(args, pattern);
dbuf_put_fmt(buff_suid, ":%s ", source_p->id);
dbuf_put_args(buff_suid, pattern, args);
send_format(buffer, pattern, args);
va_end(args);

++current_serial;

DLINK_FOREACH(ptr, global_serv_list.head)
DLINK_FOREACH_SAFE(ptr, ptr_next, global_serv_list.head)
{
struct Client *target_p = ptr->data;

@@ -806,11 +806,11 @@ sendto_match_servs(struct Client *source_p, const char *mask, unsigned int cap,
if (!IsCapable(target_p->from, cap))
continue;

send_message_remote(target_p->from, source_p, buff_suid);
send_message_remote(target_p->from, source_p, buffer);
}
}

dbuf_ref_free(buff_suid);
dbuf_ref_free(buffer);
}

/* sendto_anywhere()
@@ -282,14 +282,11 @@ try_connections(void *unused)
if (conf->until > CurrentTime)
continue;

if (conf->class == NULL)
confrq = DEFAULT_CONNECTFREQUENCY;
else
{
confrq = conf->class->con_freq;
if (confrq < MIN_CONN_FREQ)
confrq = MIN_CONN_FREQ;
}
assert(conf->class);

confrq = conf->class->con_freq;
if (confrq < MIN_CONN_FREQ)
confrq = MIN_CONN_FREQ;

conf->until = CurrentTime + confrq;

@@ -513,24 +510,22 @@ find_capability(const char *capab)
void
send_capabilities(struct Client *client_p, int cap_can_send)
{
char msgbuf[IRCD_BUFSIZE] = "";
char *t = msgbuf;
int tl;
dlink_node *ptr = NULL;
char buf[IRCD_BUFSIZE] = "";
const dlink_node *ptr = NULL;

DLINK_FOREACH(ptr, cap_list.head)
{
struct Capability *cap = ptr->data;
const struct Capability *cap = ptr->data;

if (cap->cap & (cap_can_send|default_server_capabs))
{
tl = sprintf(t, "%s ", cap->name);
t += tl;
strlcat(buf, cap->name, sizeof(buf));
if (ptr->next)
strlcat(buf, " ", sizeof(buf));
}
}

*(t - 1) = '\0';
sendto_one(client_p, "CAPAB :%s", msgbuf);
sendto_one(client_p, "CAPAB :%s", buf);
}

/*
@@ -877,10 +872,9 @@ ssl_server_handshake(fde_t *fd, struct Client *client_p)
{
unsigned int n = 0;

if (X509_digest(cert, EVP_sha256(), md, &n))
if (X509_digest(cert, ServerInfo.message_digest_algorithm, md, &n))
{
for (unsigned int i = 0; i < n; ++i)
snprintf(buf + 2 * i, 3, "%02X", md[i]);
binary_to_hex(md, buf, n);
client_p->certfp = xstrdup(buf);
}
}