diff options
Diffstat (limited to 'src/modules')
42 files changed, 448 insertions, 300 deletions
diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp index 3561d1a5d..d21a82149 100644 --- a/src/modules/extra/m_geoip.cpp +++ b/src/modules/extra/m_geoip.cpp @@ -46,7 +46,9 @@ class ModuleGeoIP : public Module } public: - ModuleGeoIP() : ext("geoip_cc", this), gi(NULL) + ModuleGeoIP() + : ext("geoip_cc", ExtensionItem::EXT_USER, this) + , gi(NULL) { } diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index 9833c720d..d3490acc0 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -50,7 +50,7 @@ class BanRedirect : public ModeWatcher BanRedirect(Module* parent) : ModeWatcher(parent, "ban", MODETYPE_CHANNEL) , ban(parent, "ban") - , extItem("banredirect", parent) + , extItem("banredirect", ExtensionItem::EXT_CHANNEL, parent) { } diff --git a/src/modules/m_blockamsg.cpp b/src/modules/m_blockamsg.cpp index b456606a8..9614203c3 100644 --- a/src/modules/m_blockamsg.cpp +++ b/src/modules/m_blockamsg.cpp @@ -53,7 +53,8 @@ class ModuleBlockAmsg : public Module SimpleExtItem<BlockedMessage> blockamsg; public: - ModuleBlockAmsg() : blockamsg("blockamsg", this) + ModuleBlockAmsg() + : blockamsg("blockamsg", ExtensionItem::EXT_USER, this) { } diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp index efbf1a81b..5c6d14a90 100644 --- a/src/modules/m_callerid.cpp +++ b/src/modules/m_callerid.cpp @@ -69,7 +69,7 @@ class callerid_data struct CallerIDExtInfo : public ExtensionItem { CallerIDExtInfo(Module* parent) - : ExtensionItem("callerid_data", parent) + : ExtensionItem("callerid_data", ExtensionItem::EXT_USER, parent) { } diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index bc79e59ec..db5d85f0f 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -42,7 +42,7 @@ class CommandCAP : public Command public: LocalIntExt reghold; CommandCAP (Module* mod) : Command(mod, "CAP", 1), - reghold("CAP_REGHOLD", mod) + reghold("CAP_REGHOLD", ExtensionItem::EXT_USER, mod) { works_before_reg = true; } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 791045780..721d6ba08 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -74,7 +74,8 @@ class CommandWebirc : public Command CGIHostlist Hosts; CommandWebirc(Module* Creator) : Command(Creator, "WEBIRC", 4), - realhost("cgiirc_realhost", Creator), realip("cgiirc_realip", Creator) + realhost("cgiirc_realhost", ExtensionItem::EXT_USER, Creator) + , realip("cgiirc_realip", ExtensionItem::EXT_USER, Creator) { works_before_reg = true; this->syntax = "password client hostname ip"; @@ -225,7 +226,7 @@ class ModuleCgiIRC : public Module public: ModuleCgiIRC() : cmd(this) - , waiting("cgiirc-delay", this) + , waiting("cgiirc-delay", ExtensionItem::EXT_USER, this) , DNS(this, "DNS") { } diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index d0e7313b7..1534043ce 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -49,7 +49,7 @@ class CloakUser : public ModeHandler CloakUser(Module* source) : ModeHandler(source, "cloak", 'x', PARAM_NONE, MODETYPE_USER), - ext("cloaked_host", source), debounce_ts(0), debounce_count(0) + ext("cloaked_host", ExtensionItem::EXT_USER, source), debounce_ts(0), debounce_count(0) { } diff --git a/src/modules/m_conn_join.cpp b/src/modules/m_conn_join.cpp index d5a095e7f..b22dbdf4d 100644 --- a/src/modules/m_conn_join.cpp +++ b/src/modules/m_conn_join.cpp @@ -66,7 +66,8 @@ class ModuleConnJoin : public Module unsigned int defdelay; public: - ModuleConnJoin() : ext("join_timer", this) + ModuleConnJoin() + : ext("join_timer", ExtensionItem::EXT_USER, this) { } diff --git a/src/modules/m_conn_waitpong.cpp b/src/modules/m_conn_waitpong.cpp index 496b04c2d..87b6b51f2 100644 --- a/src/modules/m_conn_waitpong.cpp +++ b/src/modules/m_conn_waitpong.cpp @@ -32,7 +32,7 @@ class ModuleWaitPong : public Module public: ModuleWaitPong() - : ext("waitpong_pingstr", this) + : ext("waitpong_pingstr", ExtensionItem::EXT_USER, this) { } diff --git a/src/modules/m_customtitle.cpp b/src/modules/m_customtitle.cpp index 3386e8cd7..67eca6dda 100644 --- a/src/modules/m_customtitle.cpp +++ b/src/modules/m_customtitle.cpp @@ -28,7 +28,7 @@ class CommandTitle : public Command public: StringExtItem ctitle; CommandTitle(Module* Creator) : Command(Creator,"TITLE", 2), - ctitle("ctitle", Creator) + ctitle("ctitle", ExtensionItem::EXT_USER, Creator) { syntax = "<user> <password>"; } diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 7627ba8c7..2b8d1306c 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -257,7 +257,7 @@ class ModuleDCCAllow : public Module public: ModuleDCCAllow() - : ext("dccallow", this) + : ext("dccallow", ExtensionItem::EXT_USER, this) , cmd(this, ext) { } diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp index 7e800572e..e864a8289 100644 --- a/src/modules/m_delayjoin.cpp +++ b/src/modules/m_delayjoin.cpp @@ -39,7 +39,9 @@ class ModuleDelayJoin : public Module DelayJoinMode djm; public: LocalIntExt unjoined; - ModuleDelayJoin() : djm(this), unjoined("delayjoin", this) + ModuleDelayJoin() + : djm(this) + , unjoined("delayjoin", ExtensionItem::EXT_MEMBERSHIP, this) { } diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index 32a0ba96e..f64297e15 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -25,7 +25,7 @@ class DelayMsgMode : public ParamMode<DelayMsgMode, LocalIntExt> LocalIntExt jointime; DelayMsgMode(Module* Parent) : ParamMode<DelayMsgMode, LocalIntExt>(Parent, "delaymsg", 'd') - , jointime("delaymsg", Parent) + , jointime("delaymsg", ExtensionItem::EXT_MEMBERSHIP, Parent) { levelrequired = OP_VALUE; } diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 63dda547f..7b38da4bf 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -236,7 +236,12 @@ class ModuleDNSBL : public Module return DNSBLConfEntry::I_UNKNOWN; } public: - ModuleDNSBL() : DNS(this, "DNS"), nameExt("dnsbl_match", this), countExt("dnsbl_pending", this) { } + ModuleDNSBL() + : DNS(this, "DNS") + , nameExt("dnsbl_match", ExtensionItem::EXT_USER, this) + , countExt("dnsbl_pending", ExtensionItem::EXT_USER, this) + { + } Version GetVersion() CXX11_OVERRIDE { diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index 3e87b8c5a..959e58a47 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -277,7 +277,8 @@ class ModuleIdent : public Module bool NoLookupPrefix; SimpleExtItem<IdentRequestSocket, stdalgo::culldeleter> ext; public: - ModuleIdent() : ext("ident_socket", this) + ModuleIdent() + : ext("ident_socket", ExtensionItem::EXT_USER, this) { } diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index 4eb54d2a6..b1c04cdf5 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -20,6 +20,26 @@ #include "modules/account.h" #include "modules/cap.h" +class WriteNeighboursWithExt : public User::ForEachNeighborHandler +{ + const LocalIntExt& ext; + const std::string& msg; + + void Execute(LocalUser* user) CXX11_OVERRIDE + { + if (ext.get(user)) + user->Write(msg); + } + + public: + WriteNeighboursWithExt(User* user, const std::string& message, const LocalIntExt& extension) + : ext(extension) + , msg(message) + { + user->ForEachNeighbor(*this, false); + } +}; + class ModuleIRCv3 : public Module { GenericCap cap_accountnotify; @@ -31,44 +51,6 @@ class ModuleIRCv3 : public Module CUList last_excepts; - void WriteNeighboursWithExt(User* user, const std::string& line, const LocalIntExt& ext) - { - IncludeChanList chans(user->chans.begin(), user->chans.end()); - - std::map<User*, bool> exceptions; - FOREACH_MOD(OnBuildNeighborList, (user, chans, exceptions)); - - // Send it to all local users who were explicitly marked as neighbours by modules and have the required ext - for (std::map<User*, bool>::const_iterator i = exceptions.begin(); i != exceptions.end(); ++i) - { - LocalUser* u = IS_LOCAL(i->first); - if ((u) && (i->second) && (ext.get(u))) - u->Write(line); - } - - // Now consider sending it to all other users who has at least a common channel with the user - std::set<User*> already_sent; - for (IncludeChanList::const_iterator i = chans.begin(); i != chans.end(); ++i) - { - const Channel::MemberMap& userlist = (*i)->chan->GetUsers(); - for (Channel::MemberMap::const_iterator m = userlist.begin(); m != userlist.end(); ++m) - { - /* - * Send the line if the channel member in question meets all of the following criteria: - * - local - * - not the user who is doing the action (i.e. whose channels we're iterating) - * - has the given extension - * - not on the except list built by modules - * - we haven't sent the line to the member yet - * - */ - LocalUser* member = IS_LOCAL(m->first); - if ((member) && (member != user) && (ext.get(member)) && (exceptions.find(member) == exceptions.end()) && (already_sent.insert(member).second)) - member->Write(line); - } - } - } - public: ModuleIRCv3() : cap_accountnotify(this, "account-notify"), cap_awaynotify(this, "away-notify"), diff --git a/src/modules/m_kicknorejoin.cpp b/src/modules/m_kicknorejoin.cpp index fdb7b8f24..ebe2d45c9 100644 --- a/src/modules/m_kicknorejoin.cpp +++ b/src/modules/m_kicknorejoin.cpp @@ -25,14 +25,58 @@ #include "inspircd.h" -typedef std::map<std::string, time_t> delaylist; - -struct KickRejoinData +class KickRejoinData { - delaylist kicked; - unsigned int delay; + struct KickedUser + { + std::string uuid; + time_t expire; + + KickedUser(User* user, unsigned int Delay) + : uuid(user->uuid) + , expire(ServerInstance->Time() + Delay) + { + } + }; + + typedef std::vector<KickedUser> KickedList; + + mutable KickedList kicked; + + public: + const unsigned int delay; KickRejoinData(unsigned int Delay) : delay(Delay) { } + + bool canjoin(LocalUser* user) const + { + for (KickedList::iterator i = kicked.begin(); i != kicked.end(); ) + { + KickedUser& rec = *i; + if (rec.expire > ServerInstance->Time()) + { + if (rec.uuid == user->uuid) + return false; + ++i; + } + else + { + // Expired record, remove. + stdalgo::vector::swaperase(kicked, i); + if (kicked.empty()) + break; + } + } + return true; + } + + void add(User* user) + { + // One user can be in the list multiple times if the user gets kicked, force joins + // (skipping OnUserPreJoin) and gets kicked again, but that's okay because canjoin() + // works correctly in this case as well + kicked.push_back(KickedUser(user, delay)); + } }; /** Handles channel mode +J @@ -79,28 +123,11 @@ public: { if (chan) { - KickRejoinData* data = kr.ext.get(chan); - if (data) + const KickRejoinData* data = kr.ext.get(chan); + if ((data) && (!data->canjoin(user))) { - delaylist& kicked = data->kicked; - for (delaylist::iterator iter = kicked.begin(); iter != kicked.end(); ) - { - if (iter->second > ServerInstance->Time()) - { - if (iter->first == user->uuid) - { - user->WriteNumeric(ERR_DELAYREJOIN, "%s :You must wait %u seconds after being kicked to rejoin (+J)", - chan->name.c_str(), data->delay); - return MOD_RES_DENY; - } - ++iter; - } - else - { - // Expired record, remove. - kicked.erase(iter++); - } - } + user->WriteNumeric(ERR_DELAYREJOIN, "%s :You must wait %u seconds after being kicked to rejoin (+J)", chan->name.c_str(), data->delay); + return MOD_RES_DENY; } } return MOD_RES_PASSTHRU; @@ -114,7 +141,7 @@ public: KickRejoinData* data = kr.ext.get(memb->chan); if (data) { - data->kicked[memb->user->uuid] = ServerInstance->Time() + data->delay; + data->add(memb->user); } } diff --git a/src/modules/m_ldapauth.cpp b/src/modules/m_ldapauth.cpp index eee357ec0..804f6b821 100644 --- a/src/modules/m_ldapauth.cpp +++ b/src/modules/m_ldapauth.cpp @@ -307,8 +307,8 @@ class ModuleLDAPAuth : public Module public: ModuleLDAPAuth() : LDAP(this, "LDAP") - , ldapAuthed("ldapauth", this) - , ldapVhost("ldapauth_vhost", this) + , ldapAuthed("ldapauth", ExtensionItem::EXT_USER, this) + , ldapVhost("ldapauth_vhost", ExtensionItem::EXT_USER, this) { me = this; authed = &ldapAuthed; diff --git a/src/modules/m_mlock.cpp b/src/modules/m_mlock.cpp index d9c43ec10..9b0fa8dab 100644 --- a/src/modules/m_mlock.cpp +++ b/src/modules/m_mlock.cpp @@ -25,7 +25,7 @@ class ModuleMLock : public Module public: ModuleMLock() - : mlock("mlock", this) + : mlock("mlock", ExtensionItem::EXT_CHANNEL, this) { } diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp index 9bf16498a..8ac2e8b47 100644 --- a/src/modules/m_nicklock.cpp +++ b/src/modules/m_nicklock.cpp @@ -144,7 +144,9 @@ class ModuleNickLock : public Module CommandNickunlock cmd2; public: ModuleNickLock() - : locked("nick_locked", this), cmd1(this, locked), cmd2(this, locked) + : locked("nick_locked", ExtensionItem::EXT_USER, this) + , cmd1(this, locked) + , cmd2(this, locked) { } diff --git a/src/modules/m_repeat.cpp b/src/modules/m_repeat.cpp index ca6955040..820ef702f 100644 --- a/src/modules/m_repeat.cpp +++ b/src/modules/m_repeat.cpp @@ -122,7 +122,7 @@ class RepeatMode : public ParamMode<RepeatMode, SimpleExtItem<ChannelSettings> > RepeatMode(Module* Creator) : ParamMode<RepeatMode, SimpleExtItem<ChannelSettings> >(Creator, "repeat", 'E') - , MemberInfoExt("repeat_memb", Creator) + , MemberInfoExt("repeat_memb", ExtensionItem::EXT_MEMBERSHIP, Creator) { } diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 074362651..0a2c840bd 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -249,7 +249,10 @@ class ModuleSASL : public Module public: ModuleSASL() - : authExt("sasl_auth", this), cap(this, "sasl"), auth(this, authExt, cap), sasl(this, authExt) + : authExt("sasl_auth", ExtensionItem::EXT_USER, this) + , cap(this, "sasl") + , auth(this, authExt, cap) + , sasl(this, authExt) { } diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp index 9630128e0..aac0b9ce0 100644 --- a/src/modules/m_services_account.cpp +++ b/src/modules/m_services_account.cpp @@ -106,15 +106,13 @@ class AccountExtItemImpl : public AccountExtItem { public: AccountExtItemImpl(Module* mod) - : AccountExtItem("accountname", mod) + : AccountExtItem("accountname", ExtensionItem::EXT_USER, mod) { } void unserialize(SerializeFormat format, Extensible* container, const std::string& value) { - User* user = dynamic_cast<User*>(container); - if (!user) - return; + User* user = static_cast<User*>(container); StringExtItem::unserialize(format, container, value); if (!value.empty()) diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index 22de0ac8b..91822b4e4 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -106,7 +106,8 @@ class CommandSilence : public Command public: SimpleExtItem<silencelist> ext; CommandSilence(Module* Creator, unsigned int &max) : Command(Creator, "SILENCE", 0), - maxsilence(max), ext("silence_list", Creator) + maxsilence(max) + , ext("silence_list", ExtensionItem::EXT_USER, Creator) { allow_empty_last_param = false; syntax = "{[+|-]<mask> <p|c|i|n|t|a|x>}"; diff --git a/src/modules/m_spanningtree/commandbuilder.h b/src/modules/m_spanningtree/commandbuilder.h index c2b438deb..26eb4587f 100644 --- a/src/modules/m_spanningtree/commandbuilder.h +++ b/src/modules/m_spanningtree/commandbuilder.h @@ -75,6 +75,13 @@ class CmdBuilder return *this; } + template <typename InputIterator> + CmdBuilder& push_raw(InputIterator first, InputIterator last) + { + content.append(first, last); + return *this; + } + CmdBuilder& push(const std::string& s) { content.push_back(' '); diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h index 89bd2bfee..1f7456426 100644 --- a/src/modules/m_spanningtree/commands.h +++ b/src/modules/m_spanningtree/commands.h @@ -114,6 +114,7 @@ class CommandOpertype : public UserOnlyServerCommand<CommandOpertype> }; class TreeSocket; +class FwdFJoinBuilder; class CommandFJoin : public ServerCommand { /** Remove all modes from a channel, including statusmodes (+qaovh etc), simplemodes, parameter modes. @@ -129,10 +130,11 @@ class CommandFJoin : public ServerCommand * @param newname The new name of the channel; must be the same or a case change of the current name */ static void LowerTS(Channel* chan, time_t TS, const std::string& newname); - void ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist); + void ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist, FwdFJoinBuilder& fwdfjoin); public: CommandFJoin(Module* Creator) : ServerCommand(Creator, "FJOIN", 3) { } CmdResult Handle(User* user, std::vector<std::string>& params); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { return ROUTE_LOCALONLY; } class Builder : public CmdBuilder { @@ -140,13 +142,25 @@ class CommandFJoin : public ServerCommand * a message or not */ static const size_t membid_max_digits = 20; - static const size_t maxline = 480; + static const size_t maxline = 510; std::string::size_type pos; + protected: + void add(Membership* memb, std::string::const_iterator mbegin, std::string::const_iterator mend); + bool has_room(std::string::size_type nummodes) const; + public: - Builder(Channel* chan); - void add(Membership* memb); - bool has_room(Membership* memb) const; + Builder(Channel* chan, TreeServer* source = Utils->TreeRoot); + void add(Membership* memb) + { + add(memb, memb->modes.begin(), memb->modes.end()); + } + + bool has_room(Membership* memb) const + { + return has_room(memb->modes.size()); + } + void clear(); const std::string& finalize(); }; diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index bfe3592d2..25c1f6678 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -25,6 +25,22 @@ #include "treeserver.h" #include "treesocket.h" +/** FJOIN builder for rebuilding incoming FJOINs and splitting them up into multiple messages if necessary + */ +class FwdFJoinBuilder : public CommandFJoin::Builder +{ + TreeServer* const sourceserver; + + public: + FwdFJoinBuilder(Channel* chan, TreeServer* server) + : CommandFJoin::Builder(chan, server) + , sourceserver(server) + { + } + + void add(Membership* memb, std::string::const_iterator mbegin, std::string::const_iterator mend); +}; + /** FJOIN, almost identical to TS6 SJOIN, except for nicklist handling. */ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params) { @@ -72,6 +88,30 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params) * <membid> is a positive integer representing the id of the membership. * If not present (in FJOINs coming from pre-1205 servers), 0 is assumed. * + * Forwarding: + * FJOIN messages are forwarded with the new TS and modes. Prefix modes of + * members on the losing side are not forwarded. + * This is required to only have one server on each side of the network who + * decides the fate of a channel during a network merge. Otherwise, if the + * clock of a server is slightly off it may make a different decision than + * the rest of the network and desync. + * The prefix modes are always forwarded as-is, or not at all. + * One incoming FJOIN may result in more than one FJOIN being generated + * and forwarded mainly due to compatibility reasons with non-InspIRCd + * servers that don't handle more than 512 char long lines. + * + * Forwarding examples: + * Existing channel #chan with TS 1000, modes +n. + * Incoming: :220 FJOIN #chan 1000 +t :o,220AAAAAB:0 + * Forwarded: :220 FJOIN #chan 1000 +nt :o,220AAAAAB:0 + * Merge modes and forward the result. Forward their prefix modes as well. + * + * Existing channel #chan with TS 1000, modes +nt. + * Incoming: :220 FJOIN #CHAN 2000 +i :ov,220AAAAAB:0 o,220AAAAAC:20 + * Forwarded: :220 FJOIN #chan 1000 +nt :,220AAAAAB:0 ,220AAAAAC:20 + * Drop their modes, forward our modes and TS, use our channel name + * capitalization. Don't forward prefix modes. + * */ time_t TS = ServerCommand::ExtractTS(params[1]); @@ -124,15 +164,22 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params) TreeServer* const sourceserver = TreeServer::Get(srcuser); + // Build a new FJOIN for forwarding. Put the correct TS in it and the current modes of the channel + // after applying theirs. If they lost, the prefix modes from their message are not forwarded. + FwdFJoinBuilder fwdfjoin(chan, sourceserver); + /* Now, process every 'modes,uuid' pair */ irc::tokenstream users(params.back()); std::string item; Modes::ChangeList* modechangelistptr = (apply_other_sides_modes ? &modechangelist : NULL); while (users.GetToken(item)) { - ProcessModeUUIDPair(item, sourceserver, chan, modechangelistptr); + ProcessModeUUIDPair(item, sourceserver, chan, modechangelistptr, fwdfjoin); } + fwdfjoin.finalize(); + fwdfjoin.Forward(sourceserver); + // Set prefix modes on their users if we lost the FJOIN or had equal TS if (apply_other_sides_modes) ServerInstance->Modes->Process(srcuser, chan, NULL, modechangelist, ModeParser::MODE_LOCALONLY); @@ -140,7 +187,7 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params) return CMD_SUCCESS; } -void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist) +void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist, FwdFJoinBuilder& fwdfjoin) { std::string::size_type comma = item.find(','); @@ -162,12 +209,13 @@ void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sour return; } + std::string::const_iterator modeendit = item.begin(); // End of the "ov" mode string /* Check if the user received at least one mode */ - if ((modechangelist) && (comma > 0) && (comma != std::string::npos)) + if ((modechangelist) && (comma != std::string::npos)) { + modeendit += comma; /* Iterate through the modes and see if they are valid here, if so, apply */ - std::string::const_iterator commait = item.begin()+comma; - for (std::string::const_iterator i = item.begin(); i != commait; ++i) + for (std::string::const_iterator i = item.begin(); i != modeendit; ++i) { ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL); if (!mh) @@ -180,7 +228,13 @@ void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sour Membership* memb = chan->ForceJoin(who, NULL, sourceserver->IsBursting()); if (!memb) + { + // User was already on the channel, forward because of the modes they potentially got + memb = chan->GetUser(who); + if (memb) + fwdfjoin.add(memb, item.begin(), modeendit); return; + } // Assign the id to the new Membership Membership::Id membid = 0; @@ -188,6 +242,9 @@ void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sour if (colon != std::string::npos) membid = Membership::IdFromString(item.substr(colon+1)); memb->id = membid; + + // Add member to fwdfjoin with prefix modes + fwdfjoin.add(memb, item.begin(), modeendit); } void CommandFJoin::RemoveStatus(Channel* c) @@ -237,24 +294,24 @@ void CommandFJoin::LowerTS(Channel* chan, time_t TS, const std::string& newname) chan->topicset = 0; } -CommandFJoin::Builder::Builder(Channel* chan) - : CmdBuilder("FJOIN") +CommandFJoin::Builder::Builder(Channel* chan, TreeServer* source) + : CmdBuilder(source->GetID(), "FJOIN") { push(chan->name).push_int(chan->age).push_raw(" +"); pos = str().size(); push_raw(chan->ChanModes(true)).push_raw(" :"); } -void CommandFJoin::Builder::add(Membership* memb) +void CommandFJoin::Builder::add(Membership* memb, std::string::const_iterator mbegin, std::string::const_iterator mend) { - push_raw(memb->modes).push_raw(',').push_raw(memb->user->uuid); + push_raw(mbegin, mend).push_raw(',').push_raw(memb->user->uuid); push_raw(':').push_raw_int(memb->id); push_raw(' '); } -bool CommandFJoin::Builder::has_room(Membership* memb) const +bool CommandFJoin::Builder::has_room(std::string::size_type nummodes) const { - return ((str().size() + memb->modes.size() + UIDGenerator::UUID_LENGTH + 2 + membid_max_digits + 1) <= maxline); + return ((str().size() + nummodes + UIDGenerator::UUID_LENGTH + 2 + membid_max_digits + 1) <= maxline); } void CommandFJoin::Builder::clear() @@ -269,3 +326,20 @@ const std::string& CommandFJoin::Builder::finalize() content.erase(content.size()-1); return str(); } + +void FwdFJoinBuilder::add(Membership* memb, std::string::const_iterator mbegin, std::string::const_iterator mend) +{ + // Pseudoserver compatibility: + // Some pseudoservers do not handle lines longer than 512 so we split long FJOINs into multiple messages. + // The forwarded FJOIN can end up being longer than the original one if we have more modes set and won, for example. + + // Check if the member fits into the current message. If not, send it and prepare a new one. + if (!has_room(std::distance(mbegin, mend))) + { + finalize(); + Forward(sourceserver); + clear(); + } + // Add the member and their modes exactly as they sent them + CommandFJoin::Builder::add(memb, mbegin, mend); +} diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index c21064683..31d822789 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -153,64 +153,6 @@ std::string ModuleSpanningTree::TimeToStr(time_t secs) + ConvToStr(secs) + "s"); } -void ModuleSpanningTree::DoPingChecks(time_t curtime) -{ - /* - * Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data. - * This prevents lost REMOTECONNECT notices - */ - long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); - -restart: - for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++) - { - TreeServer *s = i->second; - - // Skip myself - if (s->IsRoot()) - continue; - - // Do not ping servers that are not fully connected yet! - // Servers which are connected to us have IsLocal() == true and if they're fully connected - // then Socket->LinkState == CONNECTED. Servers that are linked to another server are always fully connected. - if (s->IsLocal() && s->GetSocket()->GetLinkState() != CONNECTED) - continue; - - // Now do PING checks on all servers - // Only ping if this server needs one - if (curtime >= s->NextPingTime()) - { - // And if they answered the last - if (s->AnsweredLastPing()) - { - // They did, send a ping to them - s->SetNextPingTime(curtime + Utils->PingFreq); - s->GetSocket()->WriteLine(CmdBuilder("PING").push(s->GetID())); - s->LastPingMsec = ts; - } - else - { - // They didn't answer the last ping, if they are locally connected, get rid of them. - if (s->IsLocal()) - { - TreeSocket* sock = s->GetSocket(); - sock->SendError("Ping timeout"); - sock->Close(); - goto restart; - } - } - } - - // If warn on ping enabled and not warned and the difference is sufficient and they didn't answer the last ping... - if ((Utils->PingWarnTime) && (!s->Warned) && (curtime >= s->NextPingTime() - (Utils->PingFreq - Utils->PingWarnTime)) && (!s->AnsweredLastPing())) - { - /* The server hasnt responded, send a warning to opers */ - ServerInstance->SNO->WriteToSnoMask('l',"Server \002%s\002 has not responded to PING for %d seconds, high latency.", s->GetName().c_str(), Utils->PingWarnTime); - s->Warned = true; - } - } -} - void ModuleSpanningTree::ConnectServer(Autoconnect* a, bool on_timer) { if (!a) @@ -471,7 +413,6 @@ void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, void ModuleSpanningTree::OnBackgroundTimer(time_t curtime) { AutoConnectServers(curtime); - DoPingChecks(curtime); DoConnectTimeout(curtime); } diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index c81eb2d0b..13c743f73 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -103,10 +103,6 @@ class ModuleSpanningTree : public Module */ ModResult HandleRemoteWhois(const std::vector<std::string>& parameters, User* user); - /** Ping all local servers - */ - void DoPingChecks(time_t curtime); - /** Connect a server locally */ void ConnectServer(Link* x, Autoconnect* y = NULL); diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp index 13ccabc35..f758754b4 100644 --- a/src/modules/m_spanningtree/metadata.cpp +++ b/src/modules/m_spanningtree/metadata.cpp @@ -49,7 +49,7 @@ CmdResult CommandMetadata::Handle(User* srcuser, std::vector<std::string>& param std::string value = params.size() < 4 ? "" : params[3]; ExtensionItem* item = ServerInstance->Extensions.GetItem(params[2]); - if (item) + if ((item) && (item->type == ExtensionItem::EXT_CHANNEL)) item->unserialize(FORMAT_NETWORK, c, value); FOREACH_MOD(OnDecodeMetaData, (c,params[2],value)); } @@ -61,7 +61,7 @@ CmdResult CommandMetadata::Handle(User* srcuser, std::vector<std::string>& param ExtensionItem* item = ServerInstance->Extensions.GetItem(params[1]); std::string value = params.size() < 3 ? "" : params[2]; - if (item) + if ((item) && (item->type == ExtensionItem::EXT_USER)) item->unserialize(FORMAT_NETWORK, u, value); FOREACH_MOD(OnDecodeMetaData, (u,params[1],value)); } diff --git a/src/modules/m_spanningtree/pingtimer.cpp b/src/modules/m_spanningtree/pingtimer.cpp new file mode 100644 index 000000000..1c96259bf --- /dev/null +++ b/src/modules/m_spanningtree/pingtimer.cpp @@ -0,0 +1,102 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com> + * + * This file is part of InspIRCd. InspIRCd 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, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "inspircd.h" + +#include "pingtimer.h" +#include "treeserver.h" +#include "commandbuilder.h" + +PingTimer::PingTimer(TreeServer* ts) + : Timer(Utils->PingFreq) + , server(ts) + , state(PS_SENDPING) +{ +} + +PingTimer::State PingTimer::TickInternal() +{ + // Timer expired, take next action based on what happened last time + if (state == PS_SENDPING) + { + // Last ping was answered, send next ping + server->GetSocket()->WriteLine(CmdBuilder("PING").push(server->GetID())); + LastPingMsec = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); + // Warn next unless warnings are disabled. If they are, jump straight to timeout. + if (Utils->PingWarnTime) + return PS_WARN; + else + return PS_TIMEOUT; + } + else if (state == PS_WARN) + { + // No pong arrived in PingWarnTime seconds, send a warning to opers + ServerInstance->SNO->WriteToSnoMask('l', "Server \002%s\002 has not responded to PING for %d seconds, high latency.", server->GetName().c_str(), GetInterval()); + return PS_TIMEOUT; + } + else // PS_TIMEOUT + { + // They didn't answer the last ping, if they are locally connected, get rid of them + if (server->IsLocal()) + { + TreeSocket* sock = server->GetSocket(); + sock->SendError("Ping timeout"); + sock->Close(); + } + + // If the server is non-locally connected, don't do anything until we get a PONG. + // This is to avoid pinging the server and warning opers more than once. + // If they do answer eventually, we will move to the PS_SENDPING state and ping them again. + return PS_IDLE; + } +} + +void PingTimer::SetState(State newstate) +{ + state = newstate; + + // Set when should the next Tick() happen based on the state + if (state == PS_SENDPING) + SetInterval(Utils->PingFreq); + else if (state == PS_WARN) + SetInterval(Utils->PingWarnTime); + else if (state == PS_TIMEOUT) + SetInterval(Utils->PingFreq - Utils->PingWarnTime); + + // If state == PS_IDLE, do not set the timer, see above why +} + +bool PingTimer::Tick(time_t currtime) +{ + if (server->IsDead()) + return false; + + SetState(TickInternal()); + return false; +} + +void PingTimer::OnPong() +{ + // Calculate RTT + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); + server->rtt = ts - LastPingMsec; + + // Change state to send ping next, also reschedules the timer appropriately + SetState(PS_SENDPING); +} diff --git a/src/modules/m_spanningtree/pingtimer.h b/src/modules/m_spanningtree/pingtimer.h new file mode 100644 index 000000000..753558689 --- /dev/null +++ b/src/modules/m_spanningtree/pingtimer.h @@ -0,0 +1,77 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com> + * + * This file is part of InspIRCd. InspIRCd 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, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#pragma once + +class TreeServer; + +/** Handles PINGing servers and killing them on timeout + */ +class PingTimer : public Timer +{ + enum State + { + /** Send PING next */ + PS_SENDPING, + /** Warn opers next */ + PS_WARN, + /** Kill the server next due to ping timeout */ + PS_TIMEOUT, + /** Do nothing */ + PS_IDLE + }; + + /** Server the timer is interacting with + */ + TreeServer* const server; + + /** What to do when the timer ticks next + */ + State state; + + /** Last ping time in milliseconds, used to calculate round trip time + */ + unsigned long LastPingMsec; + + /** Update internal state and reschedule timer according to the new state + * @param newstate State to change to + */ + void SetState(State newstate); + + /** Process timer tick event + * @return State to change to + */ + State TickInternal(); + + /** Called by the TimerManager when the timer expires + * @param currtime Time now + * @return Always false, we reschedule ourselves instead + */ + bool Tick(time_t currtime) CXX11_OVERRIDE; + + public: + /** Construct the timer. This doesn't schedule the timer. + * @param server TreeServer to interact with + */ + PingTimer(TreeServer* server); + + /** Register a PONG from the server + */ + void OnPong(); +}; diff --git a/src/modules/m_spanningtree/pong.cpp b/src/modules/m_spanningtree/pong.cpp index a7dc64f83..5d97f2af2 100644 --- a/src/modules/m_spanningtree/pong.cpp +++ b/src/modules/m_spanningtree/pong.cpp @@ -35,9 +35,7 @@ CmdResult CommandPong::HandleServer(TreeServer* server, std::vector<std::string> if (params[0] == ServerInstance->Config->GetSID()) { // PONG for us - long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); - server->rtt = ts - server->LastPingMsec; - server->SetPingFlag(); + server->OnPong(); } return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp index 98d7c8754..e004f897e 100644 --- a/src/modules/m_spanningtree/treeserver.cpp +++ b/src/modules/m_spanningtree/treeserver.cpp @@ -38,8 +38,9 @@ TreeServer::TreeServer() , VersionString(ServerInstance->GetVersionString()) , fullversion(ServerInstance->GetVersionString(true)) , Socket(NULL), sid(ServerInstance->Config->GetSID()), behind_bursting(0), isdead(false) + , pingtimer(this) , ServerUser(ServerInstance->FakeClient) - , age(ServerInstance->Time()), Warned(false), UserCount(ServerInstance->Users.GetLocalUsers().size()) + , age(ServerInstance->Time()), UserCount(ServerInstance->Users.GetLocalUsers().size()) , OperCount(0), rtt(0), StartBurst(0), Hidden(false) { AddHashEntry(); @@ -52,13 +53,14 @@ TreeServer::TreeServer() TreeServer::TreeServer(const std::string& Name, const std::string& Desc, const std::string& id, TreeServer* Above, TreeSocket* Sock, bool Hide) : Server(Name, Desc) , Parent(Above), Socket(Sock), sid(id), behind_bursting(Parent->behind_bursting), isdead(false) + , pingtimer(this) , ServerUser(new FakeUser(id, this)) - , age(ServerInstance->Time()), Warned(false), UserCount(0), OperCount(0), rtt(0), StartBurst(0), Hidden(Hide) + , age(ServerInstance->Time()), UserCount(0), OperCount(0), rtt(0), StartBurst(0), Hidden(Hide) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "New server %s behind_bursting %u", GetName().c_str(), behind_bursting); CheckULine(); - SetNextPingTime(ServerInstance->Time() + Utils->PingFreq); - SetPingFlag(); + + ServerInstance->Timers.AddTimer(&pingtimer); /* find the 'route' for this server (e.g. the one directly connected * to the local server, which we can use to reach it) @@ -112,7 +114,7 @@ TreeServer::TreeServer(const std::string& Name, const std::string& Desc, const s */ this->AddHashEntry(); - Parent->AddChild(this); + Parent->Children.push_back(this); } void TreeServer::BeginBurst(unsigned long startms) @@ -127,11 +129,6 @@ void TreeServer::BeginBurst(unsigned long startms) ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Server %s started bursting at time %lu behind_bursting %u", sid.c_str(), startms, behind_bursting); } -const std::string& TreeServer::GetID() -{ - return sid; -} - void TreeServer::FinishBurstInternal() { // Check is needed because 1202 protocol servers don't send the bursting state of a server, so servers @@ -140,11 +137,6 @@ void TreeServer::FinishBurstInternal() behind_bursting--; ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "FinishBurstInternal() %s behind_bursting %u", GetName().c_str(), behind_bursting); - if (!IsBehindBursting()) - { - SetNextPingTime(ServerInstance->Time() + Utils->PingFreq); - SetPingFlag(); - } for (ChildServers::const_iterator i = Children.begin(); i != Children.end(); ++i) { TreeServer* child = *i; @@ -168,7 +160,7 @@ void TreeServer::FinishBurst() void TreeServer::SQuitChild(TreeServer* server, const std::string& reason) { DelServerEvent(Utils->Creator, server->GetName()); - DelChild(server); + stdalgo::erase(Children, server); if (IsRoot()) { @@ -266,65 +258,6 @@ void TreeServer::AddHashEntry() Utils->sidlist[sid] = this; } -/** These accessors etc should be pretty self- - * explanitory. - */ -TreeServer* TreeServer::GetRoute() -{ - return Route; -} - -const std::string& TreeServer::GetVersion() -{ - return VersionString; -} - -void TreeServer::SetNextPingTime(time_t t) -{ - this->NextPing = t; - LastPingWasGood = false; -} - -time_t TreeServer::NextPingTime() -{ - return NextPing; -} - -bool TreeServer::AnsweredLastPing() -{ - return LastPingWasGood; -} - -void TreeServer::SetPingFlag() -{ - LastPingWasGood = true; -} - -TreeSocket* TreeServer::GetSocket() -{ - return Socket; -} - -TreeServer* TreeServer::GetParent() -{ - return Parent; -} - -void TreeServer::SetVersion(const std::string &Version) -{ - VersionString = Version; -} - -void TreeServer::AddChild(TreeServer* Child) -{ - Children.push_back(Child); -} - -bool TreeServer::DelChild(TreeServer* Child) -{ - return stdalgo::erase(Children, Child); -} - CullResult TreeServer::cull() { // Recursively cull all servers that are under us in the tree diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h index f06e0bafa..1a0203ba0 100644 --- a/src/modules/m_spanningtree/treeserver.h +++ b/src/modules/m_spanningtree/treeserver.h @@ -22,6 +22,7 @@ #pragma once #include "treesocket.h" +#include "pingtimer.h" /** Each server in the tree is represented by one class of * type TreeServer. A locally connected TreeServer can @@ -49,8 +50,6 @@ class TreeServer : public Server std::string fullversion; TreeSocket* Socket; /* Socket used to communicate with this server */ - time_t NextPing; /* After this time, the server should be PINGed*/ - bool LastPingWasGood; /* True if the server responded to the last PING with a PONG */ std::string sid; /* Server ID */ /** Counter counting how many servers are bursting in front of this server, including @@ -64,6 +63,10 @@ class TreeServer : public Server */ bool isdead; + /** Timer handling PINGing the server and killing it on timeout + */ + PingTimer pingtimer; + /** This method is used to add this TreeServer to the * hash maps. It is only called by the constructors. */ @@ -82,8 +85,6 @@ class TreeServer : public Server FakeUser* const ServerUser; /* User representing this server */ const time_t age; - bool Warned; /* True if we've warned opers about high latency on this server */ - unsigned int UserCount; /* How many users are on this server? [note: doesn't care about +i] */ unsigned int OperCount; /* How many opers are on this server? */ @@ -119,7 +120,7 @@ class TreeServer : public Server * The 'route' is defined as the locally- * connected server which can be used to reach this server. */ - TreeServer* GetRoute(); + TreeServer* GetRoute() const { return Route; } /** Returns true if this server is the tree root (i.e.: us) */ @@ -136,25 +137,13 @@ class TreeServer : public Server /** Get server version string */ - const std::string& GetVersion(); + const std::string& GetVersion() const { return VersionString; } /** Get the full version string of this server * @return The full version string of this server, including patch version and other info */ const std::string& GetFullVersion() const { return fullversion; } - /** Set time we are next due to ping this server - */ - void SetNextPingTime(time_t t); - - /** Get the time we are next due to ping this server - */ - time_t NextPingTime(); - - /** Last ping time in milliseconds, used to calculate round trip time - */ - unsigned long LastPingMsec; - /** Round trip time of last ping */ unsigned long rtt; @@ -167,27 +156,19 @@ class TreeServer : public Server */ bool Hidden; - /** True if the server answered their last ping - */ - bool AnsweredLastPing(); - - /** Set the server as responding to its last ping - */ - void SetPingFlag(); - /** Get the TreeSocket pointer for local servers. * For remote servers, this returns NULL. */ - TreeSocket* GetSocket(); + TreeSocket* GetSocket() const { return Socket; } /** Get the parent server. * For the root node, this returns NULL. */ - TreeServer* GetParent(); + TreeServer* GetParent() const { return Parent; } /** Set the server version string */ - void SetVersion(const std::string &Version); + void SetVersion(const std::string& verstr) { VersionString = verstr; } /** Set the full version string * @param verstr The version string to set @@ -204,17 +185,9 @@ class TreeServer : public Server */ const ChildServers& GetChildren() const { return Children; } - /** Add a child server - */ - void AddChild(TreeServer* Child); - - /** Delete a child server, return false if it didn't exist. - */ - bool DelChild(TreeServer* Child); - /** Get server ID */ - const std::string& GetID(); + const std::string& GetID() const { return sid; } /** Marks a server as having finished bursting and performs appropriate actions. */ @@ -242,6 +215,10 @@ class TreeServer : public Server */ void BeginBurst(unsigned long startms = 0); + /** Register a PONG from the server + */ + void OnPong() { pingtimer.OnPong(); } + CullResult cull(); /** Destructor, deletes ServerUser unless IsRoot() diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 6dc584537..4887623c1 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -174,7 +174,7 @@ class TreeSocket : public BufferedSocket /** Get link state */ - ServerState GetLinkState(); + ServerState GetLinkState() const { return LinkState; } /** Get challenge set in our CAPAB for challenge/response */ diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index d2fec0118..025bd1e61 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -69,11 +69,6 @@ TreeSocket::TreeSocket(int newfd, ListenSocket* via, irc::sockets::sockaddrs* cl Utils->timeoutlist[this] = std::pair<std::string, int>(linkID, 30); } -ServerState TreeSocket::GetLinkState() -{ - return this->LinkState; -} - void TreeSocket::CleanNegotiationInfo() { // connect is good, reset the autoconnect block (if used) diff --git a/src/modules/m_sqlauth.cpp b/src/modules/m_sqlauth.cpp index 8a0b80ce1..1a5b68dd9 100644 --- a/src/modules/m_sqlauth.cpp +++ b/src/modules/m_sqlauth.cpp @@ -78,7 +78,9 @@ class ModuleSQLAuth : public Module bool verbose; public: - ModuleSQLAuth() : pendingExt("sqlauth-wait", this), SQL(this, "SQL") + ModuleSQLAuth() + : pendingExt("sqlauth-wait", ExtensionItem::EXT_USER, this) + , SQL(this, "SQL") { } diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index c354e4e0e..f861f1236 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -22,7 +22,11 @@ class SSLCertExt : public ExtensionItem { public: - SSLCertExt(Module* parent) : ExtensionItem("ssl_cert", parent) {} + SSLCertExt(Module* parent) + : ExtensionItem("ssl_cert", ExtensionItem::EXT_USER, parent) + { + } + ssl_cert* get(const Extensible* item) const { return static_cast<ssl_cert*>(get_raw(item)); diff --git a/src/modules/m_swhois.cpp b/src/modules/m_swhois.cpp index 4eb2a9cda..81abde6f7 100644 --- a/src/modules/m_swhois.cpp +++ b/src/modules/m_swhois.cpp @@ -31,7 +31,9 @@ class CommandSwhois : public Command { public: StringExtItem swhois; - CommandSwhois(Module* Creator) : Command(Creator,"SWHOIS", 2,2), swhois("swhois", Creator) + CommandSwhois(Module* Creator) + : Command(Creator, "SWHOIS", 2, 2) + , swhois("swhois", ExtensionItem::EXT_USER, Creator) { flags_needed = 'o'; syntax = "<nick> :<swhois>"; TRANSLATE2(TR_NICK, TR_TEXT); diff --git a/src/modules/m_topiclock.cpp b/src/modules/m_topiclock.cpp index 42ed6e4c1..6053bc849 100644 --- a/src/modules/m_topiclock.cpp +++ b/src/modules/m_topiclock.cpp @@ -90,7 +90,7 @@ class FlagExtItem : public ExtensionItem { public: FlagExtItem(const std::string& key, Module* owner) - : ExtensionItem(key, owner) + : ExtensionItem(key, ExtensionItem::EXT_CHANNEL, owner) { } diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp index 9cb31a6d8..d0e42af6f 100644 --- a/src/modules/m_watch.cpp +++ b/src/modules/m_watch.cpp @@ -247,7 +247,7 @@ class CommandWatch : public Command return CMD_SUCCESS; } - CommandWatch(Module* parent, unsigned int &maxwatch) : Command(parent,"WATCH", 0), MAX_WATCH(maxwatch), ext("watchlist", parent) + CommandWatch(Module* parent, unsigned int &maxwatch) : Command(parent,"WATCH", 0), MAX_WATCH(maxwatch), ext("watchlist", ExtensionItem::EXT_USER, parent) { syntax = "[C|L|S]|[+|-<nick>]"; } |