MINIFICPP-1148 ClientSocket: fix addrinfo lifetime
MINIFICPP-1148 ClientSocket on win: reduce addr_info scope
Signed-off-by: Arpad Boda <aboda@apache.org>
This closes #727
diff --git a/libminifi/opsys/win/io/ClientSocket.h b/libminifi/opsys/win/io/ClientSocket.h
index 4e58c86..2144441 100644
--- a/libminifi/opsys/win/io/ClientSocket.h
+++ b/libminifi/opsys/win/io/ClientSocket.h
@@ -283,8 +283,6 @@
virtual int16_t select_descriptor(const uint16_t msec);
- addrinfo *addr_info_;
-
std::recursive_mutex selection_mutex_;
std::string requested_hostname_;
diff --git a/libminifi/src/io/win/ClientSocket.cpp b/libminifi/src/io/win/ClientSocket.cpp
index 2b75951..3c8b1af 100644
--- a/libminifi/src/io/win/ClientSocket.cpp
+++ b/libminifi/src/io/win/ClientSocket.cpp
@@ -26,19 +26,25 @@
#include <net/if.h>
#include <ifaddrs.h>
#include <unistd.h>
-#endif
#include <sys/types.h>
+#endif
-#include <cstdio>
#include <memory>
#include <utility>
#include <vector>
#include <cerrno>
-#include <iostream>
#include <string>
#include "io/validation.h"
#include "core/logging/LoggerConfiguration.h"
+namespace {
+struct addrinfo_deleter {
+ void operator()(addrinfo* const p) const noexcept {
+ freeaddrinfo(p);
+ }
+};
+} // namespace
+
namespace org {
namespace apache {
namespace nifi {
@@ -48,7 +54,6 @@
Socket::Socket(const std::shared_ptr<SocketContext> &context, const std::string &hostname, const uint16_t port, const uint16_t listeners = -1)
: requested_hostname_(hostname),
port_(port),
- addr_info_(0),
socket_file_descriptor_(-1),
socket_max_(0),
total_written_(0),
@@ -72,7 +77,6 @@
: requested_hostname_(std::move(other.requested_hostname_)),
port_(std::move(other.port_)),
is_loopback_only_(false),
- addr_info_(std::move(other.addr_info_)),
socket_file_descriptor_(other.socket_file_descriptor_),
socket_max_(other.socket_max_.load()),
listeners_(other.listeners_),
@@ -90,10 +94,6 @@
}
void Socket::closeStream() {
- if (0 != addr_info_) {
- freeaddrinfo(addr_info_);
- addr_info_ = 0;
- }
if (socket_file_descriptor_ >= 0 && socket_file_descriptor_ != INVALID_SOCKET) {
logging::LOG_DEBUG(logger_) << "Closing " << socket_file_descriptor_;
#ifdef WIN32
@@ -207,10 +207,8 @@
} else {
logger_->log_error("Unknown error");
}
-
#endif
closeStream();
- socket_file_descriptor_ = -1;
return -1;
}
}
@@ -241,13 +239,14 @@
hints.ai_flags |= AI_PASSIVE;
hints.ai_protocol = 0; /* any protocol */
- int errcode = getaddrinfo(requested_hostname_.c_str(), 0, &hints, &addr_info_);
-
+ addrinfo* getaddrinfo_result = nullptr;
+ const int errcode = getaddrinfo(requested_hostname_.c_str(), nullptr, &hints, &getaddrinfo_result);
if (errcode != 0) {
logger_->log_error("Saw error during getaddrinfo, error: %lu", WSAGetLastError());
return -1;
}
-
+ const std::unique_ptr<addrinfo, addrinfo_deleter> addr_info{ getaddrinfo_result };
+ getaddrinfo_result = nullptr;
socket_file_descriptor_ = -1;
#ifndef WIN32
@@ -272,8 +271,7 @@
}
memcpy(reinterpret_cast<char*>(&addr), h->h_addr_list[0], h->h_length);
- auto p = addr_info_;
- for (; p != NULL; p = p->ai_next) {
+ for (const auto* p = addr_info.get(); p; p = p->ai_next) {
if (IsNullOrEmpty(canonical_hostname_)) {
if (!IsNullOrEmpty(p) && !IsNullOrEmpty(p->ai_canonname))
canonical_hostname_ = p->ai_canonname;