From b29225601a475efe7f28fe7002eba72e70f3272b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 4 Oct 2016 02:54:35 +0200 Subject: Fix some compilation warning/errors that appear on FreeBSD --- louloulibs/network/resolver.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'louloulibs/network') diff --git a/louloulibs/network/resolver.cpp b/louloulibs/network/resolver.cpp index 9d6de23..d3ecd7c 100644 --- a/louloulibs/network/resolver.cpp +++ b/louloulibs/network/resolver.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace std::string_literals; -- cgit v1.2.3 From 45aebb8d8a3088058ae65b154496ce1fb2e3d94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 3 Oct 2016 21:12:16 +0200 Subject: Avoid an exception due to some bad logic in the DNS resolution mechanic fix #3207 --- louloulibs/network/dns_socket_handler.cpp | 3 ++- louloulibs/network/poller.cpp | 5 +++++ louloulibs/network/poller.hpp | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'louloulibs/network') 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..d341bb5 100644 --- a/louloulibs/network/poller.cpp +++ b/louloulibs/network/poller.cpp @@ -226,3 +226,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: /** -- cgit v1.2.3 From 92c99bb9dd1e431de000f085e0c6c05565fee650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 6 Oct 2016 23:53:22 +0200 Subject: Remove a branch that execute identical code in both cases fix coverity CID 134469 --- louloulibs/network/dns_handler.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'louloulibs/network') 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); } -- cgit v1.2.3 From 954d271d509356ab8042976b9add577150254b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 6 Oct 2016 23:54:39 +0200 Subject: Fix the argument of strerror after bind() fix coverity CID 134470 --- louloulibs/network/tcp_socket_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index 5420b1c..967fefe 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); } -- cgit v1.2.3 From 5f2e4820df51374ddd61b68abf35f9ee75f5a117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 12 Oct 2016 20:51:46 +0200 Subject: Fix an off-by-one issue in the POLL code --- louloulibs/network/poller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/poller.cpp b/louloulibs/network/poller.cpp index d341bb5..9868236 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(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) -- cgit v1.2.3 From 827a1eedf8936e90fe25fa851e7a13b1730f37f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 12 Oct 2016 20:53:41 +0200 Subject: On EINPROGRESS, we need to also check for read events (because openBSD lies) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit “It is possible to select(2) or poll(2) for completion by selecting the socket for writing” Yeah, sure, “writing”… --- louloulibs/network/poller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/poller.cpp b/louloulibs/network/poller.cpp index 9868236..9f5bcfb 100644 --- a/louloulibs/network/poller.cpp +++ b/louloulibs/network/poller.cpp @@ -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--; -- cgit v1.2.3 From ce06c25e93183282be42ab79bfed2ab7c02791ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Oct 2016 19:32:20 +0200 Subject: Very little optimization by using a simpler scope_guard when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The version with the vector, that can be disabled etc, is “very” slow, so we use unique_ptr when we don’t need to disable it, and when it only contains one function --- louloulibs/network/tcp_socket_handler.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index 967fefe..ca267cd 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -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) -- cgit v1.2.3 From aa4255224eb19ca55a963574fb527e1f07ff9cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Oct 2016 20:08:29 +0200 Subject: Optimize tcp_socket::on_send by using vector::erase() only once per call --- louloulibs/network/tcp_socket_handler.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index ca267cd..9d8cfea 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -305,23 +305,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(res) >= (*it).size()) + if (static_cast(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); } -- cgit v1.2.3 From 6d5d7eff6835ff0dbeca8d84bfadee127918c3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 27 Oct 2016 01:15:26 +0200 Subject: Directly use Botan::byte instead of char, to avoid an unnecessary cast --- louloulibs/network/tcp_socket_handler.cpp | 14 +++++++------- louloulibs/network/tcp_socket_handler.hpp | 5 +---- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index 9d8cfea..1adbaac 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -417,15 +417,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(recv_buf), - static_cast(size)); + this->tls->received_data(recv_buf, static_cast(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 @@ -448,9 +447,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(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(data.data()), @@ -459,7 +457,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..7bbe4d4 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -266,9 +266,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 pre_buf; #endif // BOTAN_FOUND }; - - - -- cgit v1.2.3 From 0d8a2bfd13ecd9b118f8800531ac68ba8ef8100b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 28 Oct 2016 00:11:17 +0200 Subject: Rename a variable that shadows a class member --- louloulibs/network/resolver.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'louloulibs/network') diff --git a/louloulibs/network/resolver.cpp b/louloulibs/network/resolver.cpp index d3ecd7c..2987aaa 100644 --- a/louloulibs/network/resolver.cpp +++ b/louloulibs/network/resolver.cpp @@ -117,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(addr); + current->ai_addr = reinterpret_cast(ai_addr); current->ai_next = nullptr; current->ai_canonname = nullptr; @@ -148,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(addr); + current->ai_addr = reinterpret_cast(ai_addr); current->ai_canonname = nullptr; current->ai_next = prev; -- cgit v1.2.3 From 911258bc65b3855022ee2715454076cf818d7098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 28 Oct 2016 00:11:36 +0200 Subject: Make AddrinfoDeleter a class --- louloulibs/network/resolver.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'louloulibs/network') 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 #include -struct AddrinfoDeleter +class AddrinfoDeleter { + public: void operator()(struct addrinfo* addr) { #ifdef CARES_FOUND -- cgit v1.2.3 From 3e7c8ab4bc1ea15f02dbeee51ca8894bdd70eeab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 28 Oct 2016 00:22:20 +0200 Subject: Trivial cleanup --- louloulibs/network/socket_handler.hpp | 2 +- louloulibs/network/tcp_socket_handler.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'louloulibs/network') 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 1adbaac..9decee1 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -292,7 +292,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(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); -- cgit v1.2.3 From f50f50653dc064575e4730c31b5615301f00e057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 1 Nov 2016 19:43:56 +0100 Subject: Refactor load_certs() --- louloulibs/network/credentials_manager.cpp | 47 +++++++++++++++++------------- louloulibs/network/credentials_manager.hpp | 1 + 2 files changed, 27 insertions(+), 21 deletions(-) (limited to 'louloulibs/network') 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& paths) { - // Only load the certificates the first time - if (BasicCredentialsManager::certs_loaded) - return; - const std::string conf_path = Config::get("ca_file", ""); - std::vector 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 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 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& paths); static void load_certs(); static Botan::Certificate_Store_In_Memory certificate_store; static bool certs_loaded; -- cgit v1.2.3 From 7376831bc8f6dbec8eaf4f4c0a6bba819a0a1e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 7 Nov 2016 14:43:07 +0100 Subject: Add get-irc-connection-info adhoc command fix #3171 --- louloulibs/network/tcp_socket_handler.cpp | 12 ++++++++++++ louloulibs/network/tcp_socket_handler.hpp | 3 +++ 2 files changed, 15 insertions(+) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index 9decee1..1dddde5 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -179,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 ; } @@ -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; diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 7bbe4d4..6c4235e 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -106,6 +106,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: /** -- cgit v1.2.3 From 94cebfcd77484bc79ed75307a45b6534d1899b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 7 Nov 2016 14:49:51 +0100 Subject: Add a missing include --- louloulibs/network/tcp_socket_handler.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'louloulibs/network') diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 6c4235e..20a3e5a 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3