diff --git a/include/struct.h b/include/struct.h index 1e3d6b198..092e5c190 100644 --- a/include/struct.h +++ b/include/struct.h @@ -2007,6 +2007,8 @@ struct Link { } value; }; +#define IsInvalidChannelTS(x) ((x) < 750000) /**< Invalid channel creation time */ + /** * @addtogroup CommonStructs * @{ diff --git a/src/modules/channeldb.c b/src/modules/channeldb.c index 2dcce5d63..83099d5a3 100644 --- a/src/modules/channeldb.c +++ b/src/modules/channeldb.c @@ -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; diff --git a/src/modules/mode.c b/src/modules/mode.c index 9a5168c9d..1160b48d6 100644 --- a/src/modules/mode.c +++ b/src/modules/mode.c @@ -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); diff --git a/src/modules/sjoin.c b/src/modules/sjoin.c index 7822289b3..6ff4cf2a6 100644 --- a/src/modules/sjoin.c +++ b/src/modules/sjoin.c @@ -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';