summaryrefslogtreecommitdiff
path: root/louloulibs/network
diff options
context:
space:
mode:
Diffstat (limited to 'louloulibs/network')
-rw-r--r--louloulibs/network/credentials_manager.cpp47
-rw-r--r--louloulibs/network/credentials_manager.hpp1
-rw-r--r--louloulibs/network/dns_handler.cpp6
-rw-r--r--louloulibs/network/dns_socket_handler.cpp3
-rw-r--r--louloulibs/network/poller.cpp12
-rw-r--r--louloulibs/network/poller.hpp4
-rw-r--r--louloulibs/network/resolver.cpp26
-rw-r--r--louloulibs/network/resolver.hpp3
-rw-r--r--louloulibs/network/socket_handler.hpp2
-rw-r--r--louloulibs/network/tcp_socket_handler.cpp46
-rw-r--r--louloulibs/network/tcp_socket_handler.hpp9
11 files changed, 94 insertions, 65 deletions
diff --git a/louloulibs/network/credentials_manager.cpp b/louloulibs/network/credentials_manager.cpp
index ee83c3b..ed04d24 100644
--- a/louloulibs/network/credentials_manager.cpp
+++ b/louloulibs/network/credentials_manager.cpp
@@ -29,7 +29,7 @@ BasicCredentialsManager::BasicCredentialsManager(const TCPSocketHandler* const s
socket_handler(socket_handler),
trusted_fingerprint{}
{
- this->load_certs();
+ BasicCredentialsManager::load_certs();
}
void BasicCredentialsManager::set_trusted_fingerprint(const std::string& fingerprint)
@@ -62,17 +62,8 @@ void BasicCredentialsManager::verify_certificate_chain(const std::string& type,
}
}
-void BasicCredentialsManager::load_certs()
+bool BasicCredentialsManager::try_to_open_one_ca_bundle(const std::vector<std::string>& paths)
{
- // Only load the certificates the first time
- if (BasicCredentialsManager::certs_loaded)
- return;
- const std::string conf_path = Config::get("ca_file", "");
- std::vector<std::string> paths;
- if (conf_path.empty())
- paths = default_cert_files;
- else
- paths.push_back(conf_path);
for (const auto& path: paths)
{
try
@@ -87,25 +78,39 @@ void BasicCredentialsManager::load_certs()
// will be ignored. As a result, some TLS connection may be refused
// because the certificate is signed by an issuer that was ignored.
try {
- const Botan::X509_Certificate cert(bundle);
- BasicCredentialsManager::certificate_store.add_certificate(cert);
- } catch (const Botan::Decoding_Error& error)
- {
+ Botan::X509_Certificate cert(bundle);
+ BasicCredentialsManager::certificate_store.add_certificate(std::move(cert));
+ } catch (const Botan::Decoding_Error& error) {
continue;
}
}
// Only use the first file that can successfully be read.
- goto success;
+ return true;
}
- catch (Botan::Stream_IO_Error& e)
+ catch (const Botan::Stream_IO_Error& e)
{
log_debug(e.what());
}
}
- // If we could not open one of the files, print a warning
- log_warning("The CA could not be loaded, TLS negociation will probably fail.");
- success:
- BasicCredentialsManager::certs_loaded = true;
+ return false;
+}
+
+void BasicCredentialsManager::load_certs()
+{
+ // Only load the certificates the first time
+ if (BasicCredentialsManager::certs_loaded)
+ return;
+ const std::string conf_path = Config::get("ca_file", "");
+ std::vector<std::string> paths;
+ if (conf_path.empty())
+ paths = default_cert_files;
+ else
+ paths.push_back(conf_path);
+
+ if (BasicCredentialsManager::try_to_open_one_ca_bundle(paths))
+ BasicCredentialsManager::certs_loaded = true;
+ else
+ log_warning("The CA could not be loaded, TLS negociation will probably fail.");
}
std::vector<Botan::Certificate_Store*> BasicCredentialsManager::trusted_certificate_authorities(const std::string&, const std::string&)
diff --git a/louloulibs/network/credentials_manager.hpp b/louloulibs/network/credentials_manager.hpp
index 0fc4b89..7557372 100644
--- a/louloulibs/network/credentials_manager.hpp
+++ b/louloulibs/network/credentials_manager.hpp
@@ -29,6 +29,7 @@ public:
private:
const TCPSocketHandler* const socket_handler;
+ static bool try_to_open_one_ca_bundle(const std::vector<std::string>& paths);
static void load_certs();
static Botan::Certificate_Store_In_Memory certificate_store;
static bool certs_loaded;
diff --git a/louloulibs/network/dns_handler.cpp b/louloulibs/network/dns_handler.cpp
index e267944..fef0cfc 100644
--- a/louloulibs/network/dns_handler.cpp
+++ b/louloulibs/network/dns_handler.cpp
@@ -46,11 +46,7 @@ void DNSHandler::destroy()
void DNSHandler::gethostbyname(const std::string& name, ares_host_callback callback,
void* data, int family)
{
- if (family == AF_INET)
- ::ares_gethostbyname(this->channel, name.data(), family,
- callback, data);
- else
- ::ares_gethostbyname(this->channel, name.data(), family,
+ ::ares_gethostbyname(this->channel, name.data(), family,
callback, data);
}
diff --git a/louloulibs/network/dns_socket_handler.cpp b/louloulibs/network/dns_socket_handler.cpp
index 5fd08cb..403a5be 100644
--- a/louloulibs/network/dns_socket_handler.cpp
+++ b/louloulibs/network/dns_socket_handler.cpp
@@ -42,7 +42,8 @@ bool DNSSocketHandler::is_connected() const
void DNSSocketHandler::remove_from_poller()
{
- this->poller->remove_socket_handler(this->socket);
+ if (this->poller->is_managing_socket(this->socket))
+ this->poller->remove_socket_handler(this->socket);
}
#endif /* CARES_FOUND */
diff --git a/louloulibs/network/poller.cpp b/louloulibs/network/poller.cpp
index 8a6fd97..9f5bcfb 100644
--- a/louloulibs/network/poller.cpp
+++ b/louloulibs/network/poller.cpp
@@ -95,7 +95,7 @@ void Poller::remove_socket_handler(const socket_t socket)
void Poller::watch_send_events(SocketHandler* socket_handler)
{
#if POLLER == POLL
- for (size_t i = 0; i <= this->nfds; ++i)
+ for (size_t i = 0; i < this->nfds; ++i)
{
if (this->fds[i].fd == socket_handler->get_socket())
{
@@ -171,7 +171,7 @@ int Poller::poll(const std::chrono::milliseconds& timeout)
// We cannot possibly have more ready events than the number of fds we are
// watching
assert(static_cast<unsigned int>(nb_events) <= this->nfds);
- for (size_t i = 0; i <= this->nfds && nb_events != 0; ++i)
+ for (size_t i = 0; i < this->nfds && nb_events != 0; ++i)
{
auto socket_handler = this->socket_handlers.at(this->fds[i].fd);
if (this->fds[i].revents == 0)
@@ -186,7 +186,8 @@ int Poller::poll(const std::chrono::milliseconds& timeout)
socket_handler->on_send();
nb_events--;
}
- else if (this->fds[i].revents & POLLOUT)
+ else if (this->fds[i].revents & POLLOUT ||
+ this->fds[i].revents & POLLIN)
{
socket_handler->connect();
nb_events--;
@@ -226,3 +227,8 @@ size_t Poller::size() const
{
return this->socket_handlers.size();
}
+
+bool Poller::is_managing_socket(const socket_t socket) const
+{
+ return (this->socket_handlers.find(socket) != this->socket_handlers.end());
+}
diff --git a/louloulibs/network/poller.hpp b/louloulibs/network/poller.hpp
index fc1a1a1..e39e438 100644
--- a/louloulibs/network/poller.hpp
+++ b/louloulibs/network/poller.hpp
@@ -74,6 +74,10 @@ public:
* Returns the number of SocketHandlers managed by the poller.
*/
size_t size() const;
+ /**
+ * Whether the given socket is managed by the poller
+ */
+ bool is_managing_socket(const socket_t socket) const;
private:
/**
diff --git a/louloulibs/network/resolver.cpp b/louloulibs/network/resolver.cpp
index 9d6de23..2987aaa 100644
--- a/louloulibs/network/resolver.cpp
+++ b/louloulibs/network/resolver.cpp
@@ -2,6 +2,7 @@
#include <network/resolver.hpp>
#include <string.h>
#include <arpa/inet.h>
+#include <cstdlib>
using namespace std::string_literals;
@@ -116,12 +117,13 @@ void Resolver::fill_ares_addrinfo4(const struct hostent* hostent)
current->ai_protocol = 0;
current->ai_addrlen = sizeof(struct sockaddr_in);
- struct sockaddr_in* addr = new struct sockaddr_in;
- addr->sin_family = hostent->h_addrtype;
- addr->sin_port = htons(strtoul(this->port.data(), nullptr, 10));
- addr->sin_addr.s_addr = (*address)->s_addr;
+ struct sockaddr_in* ai_addr = new struct sockaddr_in;
+
+ ai_addr->sin_family = hostent->h_addrtype;
+ ai_addr->sin_port = htons(std::strtoul(this->port.data(), nullptr, 10));
+ ai_addr->sin_addr.s_addr = (*address)->s_addr;
- current->ai_addr = reinterpret_cast<struct sockaddr*>(addr);
+ current->ai_addr = reinterpret_cast<struct sockaddr*>(ai_addr);
current->ai_next = nullptr;
current->ai_canonname = nullptr;
@@ -147,14 +149,14 @@ void Resolver::fill_ares_addrinfo6(const struct hostent* hostent)
current->ai_protocol = 0;
current->ai_addrlen = sizeof(struct sockaddr_in6);
- struct sockaddr_in6* addr = new struct sockaddr_in6;
- addr->sin6_family = hostent->h_addrtype;
- addr->sin6_port = htons(strtoul(this->port.data(), nullptr, 10));
- ::memcpy(addr->sin6_addr.s6_addr, (*address)->s6_addr, 16);
- addr->sin6_flowinfo = 0;
- addr->sin6_scope_id = 0;
+ struct sockaddr_in6* ai_addr = new struct sockaddr_in6;
+ ai_addr->sin6_family = hostent->h_addrtype;
+ ai_addr->sin6_port = htons(std::strtoul(this->port.data(), nullptr, 10));
+ ::memcpy(ai_addr->sin6_addr.s6_addr, (*address)->s6_addr, sizeof(ai_addr->sin6_addr.s6_addr));
+ ai_addr->sin6_flowinfo = 0;
+ ai_addr->sin6_scope_id = 0;
- current->ai_addr = reinterpret_cast<struct sockaddr*>(addr);
+ current->ai_addr = reinterpret_cast<struct sockaddr*>(ai_addr);
current->ai_canonname = nullptr;
current->ai_next = prev;
diff --git a/louloulibs/network/resolver.hpp b/louloulibs/network/resolver.hpp
index afe6e2b..29e6f3a 100644
--- a/louloulibs/network/resolver.hpp
+++ b/louloulibs/network/resolver.hpp
@@ -11,8 +11,9 @@
#include <sys/socket.h>
#include <netdb.h>
-struct AddrinfoDeleter
+class AddrinfoDeleter
{
+ public:
void operator()(struct addrinfo* addr)
{
#ifdef CARES_FOUND
diff --git a/louloulibs/network/socket_handler.hpp b/louloulibs/network/socket_handler.hpp
index eeb41fe..ea79a18 100644
--- a/louloulibs/network/socket_handler.hpp
+++ b/louloulibs/network/socket_handler.hpp
@@ -14,7 +14,7 @@ public:
poller(poller),
socket(socket)
{}
- virtual ~SocketHandler() {}
+ virtual ~SocketHandler() = default;
SocketHandler(const SocketHandler&) = delete;
SocketHandler(SocketHandler&&) = delete;
SocketHandler& operator=(const SocketHandler&) = delete;
diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp
index 5420b1c..1dddde5 100644
--- a/louloulibs/network/tcp_socket_handler.cpp
+++ b/louloulibs/network/tcp_socket_handler.cpp
@@ -80,7 +80,7 @@ void TCPSocketHandler::init_socket(const struct addrinfo* rp)
}
if (!rp)
log_error("Failed to bind socket to ", this->bind_addr, ": ",
- strerror(bind_error));
+ strerror(errno));
else
log_info("Socket successfully bound to ", this->bind_addr);
}
@@ -103,8 +103,6 @@ void TCPSocketHandler::connect(const std::string& address, const std::string& po
this->port = port;
this->use_tls = tls;
- utils::ScopeGuard sg;
-
struct addrinfo* addr_res;
if (!this->connecting)
@@ -181,6 +179,8 @@ void TCPSocketHandler::connect(const std::string& address, const std::string& po
if (this->use_tls)
this->start_tls();
#endif
+ this->connection_date = std::chrono::system_clock::now();
+
this->on_connected();
return ;
}
@@ -294,7 +294,8 @@ void TCPSocketHandler::on_send()
// unconsting the content of s is ok, sendmsg will never modify it
msg_iov[msg.msg_iovlen].iov_base = const_cast<char*>(s.data());
msg_iov[msg.msg_iovlen].iov_len = s.size();
- if (++msg.msg_iovlen == UIO_FASTIOV)
+ msg.msg_iovlen++;
+ if (msg.msg_iovlen == UIO_FASTIOV)
break;
}
ssize_t res = ::sendmsg(this->socket, &msg, MSG_NOSIGNAL);
@@ -307,23 +308,24 @@ void TCPSocketHandler::on_send()
else
{
// remove all the strings that were successfully sent.
- for (auto it = this->out_buf.begin();
- it != this->out_buf.end();)
+ auto it = this->out_buf.begin();
+ while (it != this->out_buf.end())
{
- if (static_cast<size_t>(res) >= (*it).size())
+ if (static_cast<size_t>(res) >= it->size())
{
- res -= (*it).size();
- it = this->out_buf.erase(it);
+ res -= it->size();
+ ++it;
}
else
{
// If one string has partially been sent, we use substr to
// crop it
if (res > 0)
- (*it) = (*it).substr(res, std::string::npos);
+ *it = it->substr(res, std::string::npos);
break;
}
}
+ this->out_buf.erase(this->out_buf.begin(), it);
if (this->out_buf.empty())
this->poller->stop_watching_send_events(this);
}
@@ -397,6 +399,16 @@ bool TCPSocketHandler::is_connecting() const
return this->connecting || this->resolver.is_resolving();
}
+bool TCPSocketHandler::is_using_tls() const
+{
+ return this->use_tls;
+}
+
+std::string TCPSocketHandler::get_port() const
+{
+ return this->port;
+}
+
void* TCPSocketHandler::get_receive_buffer(const size_t) const
{
return nullptr;
@@ -418,15 +430,14 @@ void TCPSocketHandler::start_tls()
void TCPSocketHandler::tls_recv()
{
static constexpr size_t buf_size = 4096;
- char recv_buf[buf_size];
+ Botan::byte recv_buf[buf_size];
const ssize_t size = this->do_recv(recv_buf, buf_size);
if (size > 0)
{
const bool was_active = this->tls->is_active();
try {
- this->tls->received_data(reinterpret_cast<const Botan::byte*>(recv_buf),
- static_cast<size_t>(size));
+ this->tls->received_data(recv_buf, static_cast<size_t>(size));
} catch (const Botan::TLS::TLS_Exception& e) {
// May happen if the server sends malformed TLS data (buggy server,
// or more probably we are just connected to a server that sends
@@ -449,9 +460,8 @@ void TCPSocketHandler::tls_send(std::string&& data)
const bool was_active = this->tls->is_active();
if (!this->pre_buf.empty())
{
- this->tls->send(reinterpret_cast<const Botan::byte*>(this->pre_buf.data()),
- this->pre_buf.size());
- this->pre_buf = "";
+ this->tls->send(this->pre_buf.data(), this->pre_buf.size());
+ this->pre_buf.clear();
}
if (!data.empty())
this->tls->send(reinterpret_cast<const Botan::byte*>(data.data()),
@@ -460,7 +470,9 @@ void TCPSocketHandler::tls_send(std::string&& data)
this->on_tls_activated();
}
else
- this->pre_buf += data;
+ this->pre_buf.insert(this->pre_buf.end(),
+ std::make_move_iterator(data.begin()),
+ std::make_move_iterator(data.end()));
}
void TCPSocketHandler::tls_data_cb(const Botan::byte* data, size_t size)
diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp
index b0ba493..20a3e5a 100644
--- a/louloulibs/network/tcp_socket_handler.hpp
+++ b/louloulibs/network/tcp_socket_handler.hpp
@@ -13,6 +13,7 @@
#include <netinet/in.h>
#include <netdb.h>
+#include <chrono>
#include <vector>
#include <memory>
#include <string>
@@ -106,6 +107,9 @@ public:
#endif
bool is_connected() const override final;
bool is_connecting() const;
+ bool is_using_tls() const;
+ std::string get_port() const;
+ std::chrono::system_clock::time_point connection_date;
private:
/**
@@ -266,9 +270,6 @@ private:
* An additional buffer to keep data that the user wants to send, but
* cannot because the handshake is not done.
*/
- std::string pre_buf;
+ std::vector<Botan::byte> pre_buf;
#endif // BOTAN_FOUND
};
-
-
-