summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2015-10-31 06:17:35 +0100
committerFlorent Le Coz <louiz@louiz.org>2015-10-31 06:17:35 +0100
commit34fc1d4010d23be947c00fc956f2bdded2374cee (patch)
tree51db9af976e97d37547b5bba8f1465b4a1561cf4 /src/irc
parent2c932cf0f7ca9bc82430c1da5097653f6a4d0bf4 (diff)
downloadbiboumi-34fc1d4010d23be947c00fc956f2bdded2374cee.tar.gz
biboumi-34fc1d4010d23be947c00fc956f2bdded2374cee.tar.bz2
biboumi-34fc1d4010d23be947c00fc956f2bdded2374cee.tar.xz
biboumi-34fc1d4010d23be947c00fc956f2bdded2374cee.zip
Implement a basic webirc support
See https://kiwiirc.com/docs/webirc fix #3135
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/irc_client.cpp44
-rw-r--r--src/irc/irc_client.hpp17
2 files changed, 58 insertions, 3 deletions
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index f6b8f9c..3161b85 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -26,9 +26,11 @@ using namespace std::chrono_literals;
IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
const std::string& nickname, const std::string& username,
- const std::string& realname, Bridge* bridge):
+ const std::string& realname, const std::string& user_hostname,
+ Bridge* bridge):
TCPSocketHandler(poller),
hostname(hostname),
+ user_hostname(user_hostname),
username(username),
realname(realname),
current_nick(nickname),
@@ -113,6 +115,39 @@ void IrcClient::on_connection_failed(const std::string& reason)
void IrcClient::on_connected()
{
+ const auto webirc_password = Config::get("webirc_password", "");
+ static std::string resolved_ip;
+
+ if (!webirc_password.empty())
+ {
+ if (!resolved_ip.empty())
+ this->send_webirc_command(webirc_password, resolved_ip);
+ else
+ { // Start resolving the hostname of the user, and call
+ // on_connected again when it’s done
+ this->dns_resolver.resolve(this->user_hostname, "5222",
+ [this](const struct addrinfo* addr)
+ {
+ resolved_ip = addr_to_string(addr);
+ // Only continue the process if we
+ // didn’t get connected while we were
+ // resolving
+ if (this->is_connected())
+ this->on_connected();
+ },
+ [this](const char* error_msg)
+ {
+ if (this->is_connected())
+ {
+ this->on_connection_close("Could not resolve hostname "s + this->user_hostname +
+ ": " + error_msg);
+ this->send_quit_command("");
+ }
+ });
+ return;
+ }
+ }
+
#ifdef USE_DATABASE
auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(),
this->get_hostname());
@@ -253,7 +288,7 @@ void IrcClient::send_raw(const std::string& txt)
void IrcClient::send_user_command(const std::string& username, const std::string& realname)
{
- this->send_message(IrcMessage("USER", {username, "ignored", "ignored", realname}));
+ this->send_message(IrcMessage("USER", {username, this->user_hostname, "ignored", realname}));
}
void IrcClient::send_nick_command(const std::string& nick)
@@ -266,6 +301,11 @@ void IrcClient::send_pass_command(const std::string& password)
this->send_message(IrcMessage("PASS", {password}));
}
+void IrcClient::send_webirc_command(const std::string& password, const std::string& user_ip)
+{
+ this->send_message(IrcMessage("WEBIRC", {password, "biboumi", this->user_hostname, user_ip}));
+}
+
void IrcClient::send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason)
{
this->send_message(IrcMessage("KICK", {chan_name, target, reason}));
diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp
index 7a04164..885ec84 100644
--- a/src/irc/irc_client.hpp
+++ b/src/irc/irc_client.hpp
@@ -6,6 +6,7 @@
#include <irc/iid.hpp>
#include <network/tcp_socket_handler.hpp>
+#include <network/resolver.hpp>
#include <unordered_map>
#include <utility>
@@ -27,7 +28,8 @@ class IrcClient: public TCPSocketHandler
public:
explicit IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
const std::string& nickname, const std::string& username,
- const std::string& realname, Bridge* bridge);
+ const std::string& realname, const std::string& user_hostname,
+ Bridge* bridge);
~IrcClient();
/**
* Connect to the IRC server
@@ -88,6 +90,7 @@ public:
*/
void send_nick_command(const std::string& username);
void send_pass_command(const std::string& password);
+ void send_webirc_command(const std::string& password, const std::string& user_ip);
/**
* Send the JOIN irc command.
*/
@@ -250,12 +253,19 @@ public:
std::string get_nick() const { return this->current_nick; }
bool is_welcomed() const { return this->welcomed; }
+ const Resolver& get_resolver() const;
+
private:
/**
* The hostname of the server we are connected to.
*/
const std::string hostname;
/**
+ * The hostname of the user. This is used in the USER and the WEBIRC
+ * commands, but only the one in WEBIRC will be used by the IRC server.
+ */
+ const std::string user_hostname;
+ /**
* The username used in the USER irc command
*/
std::string username;
@@ -330,6 +340,11 @@ private:
* A set of (lowercase) nicknames to which we sent a private message.
*/
std::set<std::string> nicks_to_treat_as_private;
+ /**
+ * DNS resolver, used to resolve the hostname of the user if we are using
+ * the WebIRC protocole.
+ */
+ Resolver dns_resolver;
IrcClient(const IrcClient&) = delete;
IrcClient(IrcClient&&) = delete;