mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-06 05:53:12 +02:00
Newlog and fishy timestamp handling:
* New macro IsInvalidChannelTS() which evaluates to ts < 750000
* Check for faulty creation time ("fishy timestamp") at ALL places
where channel->creationtime is set.
* Also, important, changed behavior:
if !IsInvalidChannelTS then:
1) We print our warning
2) We pretend ts is our channel creationtime (which may be
TStime() if the channel did not previously exist)
3) We allow the command through and allow it to merge (in case of SJOIN)
This makes it so we still log the error (noisy) but on the other hand
we won't get "infected" by fishy timestamps since we will never set
them, no matter what happens.
This commit is contained in:
@@ -2007,6 +2007,8 @@ struct Link {
|
||||
} value;
|
||||
};
|
||||
|
||||
#define IsInvalidChannelTS(x) ((x) < 750000) /**< Invalid channel creation time */
|
||||
|
||||
/**
|
||||
* @addtogroup CommonStructs
|
||||
* @{
|
||||
|
||||
@@ -506,7 +506,10 @@ int read_channeldb(void)
|
||||
R_SAFE(unrealdb_read_str(db, &mode_lock));
|
||||
/* If we got this far, we can create/initialize the channel with the above */
|
||||
channel = make_channel(chname);
|
||||
channel->creationtime = creationtime;
|
||||
if (IsInvalidChannelTS(creationtime))
|
||||
channel->creationtime = TStime();
|
||||
else
|
||||
channel->creationtime = creationtime;
|
||||
safe_strdup(channel->topic, topic);
|
||||
safe_strdup(channel->topic_nick, topic_nick);
|
||||
channel->topic_time = topic_time;
|
||||
|
||||
+18
-12
@@ -417,25 +417,31 @@ void _do_mode(Channel *channel, Client *client, MessageTag *recv_mtags, int parc
|
||||
{
|
||||
if (sendts > 0)
|
||||
{
|
||||
if (!channel->creationtime || sendts < channel->creationtime)
|
||||
if (IsInvalidChannelTS(sendts))
|
||||
{
|
||||
unreal_log(ULOG_WARNING, "mode", "MODE_INVALID_TIMESTAMP", NULL,
|
||||
"MODE for channel $channel has invalid timestamp $send_timestamp (from $client.name on $client.user.servername)\n"
|
||||
"Buffer: $modebuf $parabuf",
|
||||
log_data_channel("channel", channel),
|
||||
log_data_integer("send_timestamp", sendts),
|
||||
log_data_string("modebuf", modebuf),
|
||||
log_data_string("parabuf", parabuf));
|
||||
/* Yeah, so what to do in this case?
|
||||
* Don't set channel->creationtime
|
||||
* and assume merging.
|
||||
*/
|
||||
sendts = channel->creationtime;
|
||||
} else
|
||||
if (sendts < channel->creationtime)
|
||||
{
|
||||
/* Our timestamp is wrong (or this is a new channel) */
|
||||
tschange = 1;
|
||||
channel->creationtime = sendts;
|
||||
if (sendts < 750000)
|
||||
{
|
||||
sendto_realops(
|
||||
"Warning! Possible desync: MODE for channel %s ('%s %s') has fishy timestamp (%lld) (from %s/%s)",
|
||||
channel->name, modebuf, parabuf, (long long)sendts, client->direction->name, client->name);
|
||||
ircd_log(LOG_ERROR, "Possible desync: MODE for channel %s ('%s %s') has fishy timestamp (%lld) (from %s/%s)",
|
||||
channel->name, modebuf, parabuf, (long long)sendts, client->direction->name, client->name);
|
||||
}
|
||||
/* new chan or our timestamp is wrong */
|
||||
/* now works for double-bounce prevention */
|
||||
|
||||
}
|
||||
if (sendts > channel->creationtime && channel->creationtime)
|
||||
{
|
||||
/* theirs is wrong but we let it pass anyway */
|
||||
/* Their timestamp is wrong */
|
||||
sendts = channel->creationtime;
|
||||
sendto_one(client, NULL, ":%s MODE %s + %lld", me.name,
|
||||
channel->name, (long long)channel->creationtime);
|
||||
|
||||
+12
-12
@@ -178,16 +178,25 @@ CMD_FUNC(cmd_sjoin)
|
||||
if (parc < 5)
|
||||
nomode = 1;
|
||||
|
||||
ts = (time_t)atol(parv[1]);
|
||||
|
||||
channel = find_channel(parv[2]);
|
||||
if (!channel)
|
||||
{
|
||||
channel = make_channel(parv[2]);
|
||||
channel->creationtime = ts;
|
||||
oldts = -1;
|
||||
}
|
||||
|
||||
ts = (time_t)atol(parv[1]);
|
||||
|
||||
if (IsInvalidChannelTS(ts))
|
||||
{
|
||||
unreal_log(ULOG_WARNING, "sjoin", "SJOIN_INVALID_TIMESTAMP", NULL,
|
||||
"SJOIN for channel $channel has invalid timestamp $send_timestamp (from $client)",
|
||||
log_data_channel("channel", channel),
|
||||
log_data_integer("send_timestamp", ts));
|
||||
/* Pretend they match our creation time (matches U6 behavior in m_mode.c) */
|
||||
ts = channel->creationtime;
|
||||
}
|
||||
|
||||
if (channel->creationtime > ts)
|
||||
{
|
||||
removeours = 1;
|
||||
@@ -208,15 +217,6 @@ CMD_FUNC(cmd_sjoin)
|
||||
oldts = channel->creationtime;
|
||||
}
|
||||
|
||||
// FIXME: make it so services cannot screw this up so easily --- if possible...
|
||||
if (ts < 750000)
|
||||
{
|
||||
if (ts != 0)
|
||||
sendto_ops
|
||||
("Warning! Possible desync: SJOIN for channel %s has a fishy timestamp (%lld) [%s/%s]",
|
||||
channel->name, (long long)ts, client->name, client->direction->name);
|
||||
}
|
||||
|
||||
parabuf[0] = '\0';
|
||||
modebuf[0] = '+';
|
||||
modebuf[1] = '\0';
|
||||
|
||||
Reference in New Issue
Block a user