Mercurial > irccd
view lib/irccd/server-state-connecting.cpp @ 129:49d1a5eeef6f
Irccd: store server name in object like plugin, #488
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 11 May 2016 21:00:49 +0200 |
parents | 6a99814c2317 |
children | 74164ac3d01a |
line wrap: on
line source
/* * server-state-connecting.cpp -- connecting state * * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <format.h> #include "logger.hpp" #include "server-state-connecting.hpp" #include "server-state-connected.hpp" #include "server-state-disconnected.hpp" #include "server-private.hpp" #include "sysconfig.hpp" #if !defined(IRCCD_SYSTEM_WINDOWS) # include <sys/types.h> # include <netinet/in.h> # include <arpa/nameser.h> # include <resolv.h> #endif using namespace fmt::literals; namespace irccd { namespace state { namespace { bool connect(Server &server) { const ServerInfo &info = server.info(); const ServerIdentity &identity = server.identity(); const char *password = info.password.empty() ? nullptr : info.password.c_str(); std::string host = info.host; int code; /* libircclient requires # for SSL connection */ #if defined(WITH_SSL) if (info.flags & ServerInfo::Ssl) { host.insert(0, 1, '#'); } if (!(info.flags & ServerInfo::SslVerify)) { irc_option_set(server.session(), LIBIRC_OPTION_SSL_NO_VERIFY); } #endif if (info.flags & ServerInfo::Ipv6) { code = irc_connect6(server.session(), host.c_str(), info.port, password, identity.nickname.c_str(), identity.username.c_str(), identity.realname.c_str()); } else { code = irc_connect(server.session(), host.c_str(), info.port, password, identity.nickname.c_str(), identity.username.c_str(), identity.realname.c_str()); } return code == 0; } } // !namespace void Connecting::prepare(Server &server, fd_set &setinput, fd_set &setoutput, net::Handle &maxfd) { /* * The connect function will either fail if the hostname wasn't resolved or if any of the internal functions * fail. * * It returns success if the connection was successful but it does not mean that connection is established. * * Because this function will be called repeatidly, the connection was started and we're still not * connected in the specified timeout time, we mark the server as disconnected. * * Otherwise, the libircclient event_connect will change the state. */ const ServerInfo &info = server.info(); if (m_started) { const ServerSettings &settings = server.settings(); if (m_timer.elapsed() > static_cast<unsigned>(settings.reconnectDelay * 1000)) { log::warning() << "server " << server.name() << ": timeout while connecting" << std::endl; server.next(std::make_unique<state::Disconnected>()); } else if (!irc_is_connected(server.session())) { log::warning() << "server " << server.name() << ": error while connecting: "; log::warning() << irc_strerror(irc_errno(server.session())) << std::endl; if (settings.reconnectTries != 0) { log::warning("server {}: retrying in {} seconds"_format(server.name(), settings.reconnectDelay)); } server.next(std::make_unique<state::Disconnected>()); } else { irc_add_select_descriptors(server.session(), &setinput, &setoutput, reinterpret_cast<int *>(&maxfd)); } } else { /* * This is needed if irccd is started before DHCP or if * DNS cache is outdated. * * For more information see bug #190. */ #if !defined(IRCCD_SYSTEM_WINDOWS) (void)res_init(); #endif log::info("server {}: trying to connect to {}, port {}"_format(server.name(), info.host, info.port)); if (!connect(server)) { log::warning() << "server " << server.name() << ": disconnected while connecting: "; log::warning() << irc_strerror(irc_errno(server.session())) << std::endl; server.next(std::make_unique<state::Disconnected>()); } else { m_started = true; } } } std::string Connecting::ident() const { return "Connecting"; } } // !state } // !irccd