From d8da7984b23bf8f30b5f8f53895cbae5be50347a Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 12 Nov 2014 06:16:10 +0100 Subject: Implement PING, user to user only (XMPP and IRC side, using CTCP PING) ref #2757 --- src/bridge/bridge.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/bridge/bridge.hpp | 13 +++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) (limited to 'src/bridge') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index bc89073..08fd569 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -7,7 +7,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -280,6 +282,50 @@ void Bridge::send_xmpp_version_to_irc(const Iid& iid, const std::string& name, c this->send_private_message(iid, "\01VERSION "s + result + "\01", "NOTICE"); } +void Bridge::send_irc_ping_result(const Iid& iid, const std::string& id) +{ + this->send_private_message(iid, "\01PING "s + utils::revstr(id), "NOTICE"); +} + +void Bridge::send_irc_user_ping_request(const std::string& irc_hostname, const std::string& nick, + const std::string& iq_id, const std::string& to_jid, + const std::string& from_jid) +{ + Iid iid(nick + "!" + irc_hostname); + this->send_private_message(iid, "\01PING " + iq_id + "\01"); + + irc_responder_callback_t cb = [this, nick, iq_id, to_jid, irc_hostname, from_jid](const std::string& hostname, const IrcMessage& message) -> bool + { + if (irc_hostname != hostname) + return false; + IrcUser user(message.prefix); + const std::string body = message.arguments[1]; + if (message.command == "NOTICE" && user.nick == nick && + message.arguments.size() >= 2 && body.substr(0, 6) == "\01PING ") + { + const std::string id = body.substr(6, body.size() - 6); + if (id != iq_id) + return false; + Jid jid(from_jid); + this->xmpp->send_iq_result(iq_id, to_jid, jid.local); + return true; + } + if (message.command == "401" && message.arguments.size() >= 2 + && message.arguments[1] == nick) + { + std::string error_message = "No such nick"; + if (message.arguments.size() >= 3) + error_message = message.arguments[2]; + this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "service-unavailable", + error_message, true); + return true; + } + + return false; + }; + this->add_waiting_irc(std::move(cb)); +} + void Bridge::send_irc_version_request(const std::string& irc_hostname, const std::string& target, const std::string& iq_id, const std::string& to_jid, const std::string& from_jid) @@ -437,6 +483,15 @@ void Bridge::send_iq_version_request(const std::string& nick, const std::string& this->xmpp->send_iq_version_request(nick + "!" + hostname, this->user_jid); } +void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string& hostname, + const std::string& id) +{ + // Use revstr because the forwarded ping to target XMPP user must not be + // the same that the request iq, but we also need to get it back easily + // (revstr again) + this->xmpp->send_ping_request(nick + "!" + hostname, this->user_jid, utils::revstr(id)); +} + void Bridge::set_preferred_from_jid(const std::string& nick, const std::string& full_jid) { auto it = this->preferred_user_from.find(nick); diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 1f45b27..f7edfaa 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -68,9 +68,16 @@ public: void set_channel_topic(const Iid& iid, const std::string& subject); void send_xmpp_version_to_irc(const Iid& iid, const std::string& name, const std::string& version, const std::string& os); + void send_irc_ping_result(const Iid& iid, const std::string& id); void send_irc_version_request(const std::string& irc_hostname, const std::string& target, const std::string& iq_id, const std::string& to_jid, const std::string& from_jid); + /** + * Directly send a CTCP PING request to the IRC user + */ + void send_irc_user_ping_request(const std::string& irc_hostname, const std::string& nick, + const std::string& iq_id, const std::string& to_jid, + const std::string& from_jid); /*** ** @@ -128,7 +135,11 @@ public: * Send an iq version request coming from nick!hostname@ */ void send_iq_version_request(const std::string& nick, const std::string& hostname); - + /** + * Send an iq ping request coming from nick!hostname@ + */ + void send_xmpp_ping_request(const std::string& nick, const std::string& hostname, + const std::string& id); /** * Misc */ -- cgit v1.2.3