Ack. With minor comment.
Divide the following if() condition to accommodate to check the return
values of getnameinfo() and to have a TRACE to print the host name etc.
+ if (addr != nullptr &&
+ (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) &&
+ (i->ifa_flags & IFF_LOOPBACK) == 0 &&
+ (i->ifa_flags & IFF_UP) != 0 &&
+ (addr->sa_family != AF_INET6 ||
+ (!IN6_IS_ADDR_LOOPBACK(&addr_ipv6->sin6_addr) &&
+ !IN6_IS_ADDR_LINKLOCAL(&addr_ipv6->sin6_addr) &&
+ !IN6_IS_ADDR_MC_LINKLOCAL(&addr_ipv6->sin6_addr))) &&
+ getnameinfo(addr, addr->sa_family == AF_INET6 ?
+ sizeof(sockaddr_in6) : sizeof(sockaddr_in),
+ host, sizeof(host), nullptr, 0, 0) == 0 &&
+ strncmp(short_host_name.c_str(), host, short_host_name.size()) == 0
&&
+ host[short_host_name.size()] == '.') {
+ fqdn = host;
Thanks,
Ramesh.
On 2/17/2017 3:03 PM, Anders Widell wrote:
> src/base/Makefile.am | 2 +
> src/base/conf.cc | 152
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> src/base/conf.h | 106 +++++++++++++++++++++++++++++++++++
> 3 files changed, 260 insertions(+), 0 deletions(-)
>
>
> Add a new class called Conf the contains methods for reading the fully
> qualified
> domain name, the short host name and the configured OpenSAF node name.
>
> diff --git a/src/base/Makefile.am b/src/base/Makefile.am
> --- a/src/base/Makefile.am
> +++ b/src/base/Makefile.am
> @@ -32,6 +32,7 @@ lib_libopensaf_core_la_LDFLAGS += \
>
> lib_libopensaf_core_la_SOURCES += \
> src/base/condition_variable.cc \
> + src/base/conf.cc \
> src/base/daemon.c \
> src/base/file_descriptor.cc \
> src/base/file_notify.cc \
> @@ -77,6 +78,7 @@ nodist_EXTRA_lib_libopensaf_core_la_SOUR
> noinst_HEADERS += \
> src/base/buffer.h \
> src/base/condition_variable.h \
> + src/base/conf.h \
> src/base/daemon.h \
> src/base/file_descriptor.h \
> src/base/file_notify.h \
> diff --git a/src/base/conf.cc b/src/base/conf.cc
> new file mode 100644
> --- /dev/null
> +++ b/src/base/conf.cc
> @@ -0,0 +1,152 @@
> +/* -*- OpenSAF -*-
> + *
> + * Copyright Ericsson AB 2017 - All Rights Reserved.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + */
> +
> +#include "base/conf.h"
> +#include <ifaddrs.h>
> +#include <limits.h>
> +#include <net/if.h>
> +#include <netdb.h>
> +#include <netinet/in.h>
> +#include <sys/socket.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <cerrno>
> +#include <cstring>
> +#include <fstream>
> +#include "base/logtrace.h"
> +#include "base/osaf_utility.h"
> +#include "osaf/configmake.h"
> +
> +namespace base {
> +
> +pthread_once_t Conf::once_control_ = PTHREAD_ONCE_INIT;
> +Conf* Conf::instance_ = nullptr;
> +
> +Conf::Conf() :
> + fully_qualified_domain_name_{},
> + node_name_{},
> + short_host_name_{},
> + fully_qualified_domain_name_initialized_{false},
> + node_name_initialized_{false},
> + short_host_name_initialized_{false},
> + mutex_{} {
> +}
> +
> +Conf::~Conf() {
> + Lock lock(instance_->mutex_);
> + assert(instance_ == this);
> + instance_ = nullptr;
> +}
> +
> +void Conf::InitFullyQualifiedDomainName() {
> + InitShortHostName();
> + Conf* i = GetOrCreateInstance();
> + Lock lock(i->mutex_);
> + if (i->fully_qualified_domain_name_initialized_ == false) {
> + i->fully_qualified_domain_name_ =
> + GetFullyQualifiedDomainName(i->short_host_name_);
> + i->fully_qualified_domain_name_initialized_ = true;
> + }
> +}
> +
> +void Conf::InitNodeName() {
> + InitShortHostName();
> + Conf* i = GetOrCreateInstance();
> + Lock lock(i->mutex_);
> + if (i->node_name_initialized_ == false) {
> + i->node_name_ = GetNodeName(i->short_host_name_);
> + i->node_name_initialized_ = true;
> + }
> +}
> +
> +void Conf::InitShortHostName() {
> + Conf* i = GetOrCreateInstance();
> + Lock lock(i->mutex_);
> + if (i->short_host_name_initialized_ == false) {
> + i->short_host_name_ = GetShortHostName();
> + i->short_host_name_initialized_ = true;
> + }
> +}
> +
> +Conf* Conf::GetOrCreateInstance() {
> + int result = pthread_once(&once_control_, PthreadOnceInitRoutine);
> + if (result != 0) osaf_abort(result);
> + return instance_;
> +}
> +
> +void Conf::PthreadOnceInitRoutine() {
> + assert(instance_ == nullptr);
> + instance_ = new Conf();
> + if (instance_ == nullptr) osaf_abort(0);
> +}
> +
> +std::string Conf::GetFullyQualifiedDomainName(
> + const std::string& short_host_name) {
> + char host[NI_MAXHOST];
> + std::string fqdn{short_host_name};
> + ifaddrs* ifa;
> + if (getifaddrs(&ifa) == 0) {
> + for (ifaddrs* i = ifa; i != nullptr; i = i->ifa_next) {
> + sockaddr* addr = i->ifa_addr;
> + sockaddr_in6* addr_ipv6 = reinterpret_cast<sockaddr_in6*>(addr);
> + if (addr != nullptr &&
> + (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) &&
> + (i->ifa_flags & IFF_LOOPBACK) == 0 &&
> + (i->ifa_flags & IFF_UP) != 0 &&
> + (addr->sa_family != AF_INET6 ||
> + (!IN6_IS_ADDR_LOOPBACK(&addr_ipv6->sin6_addr) &&
> + !IN6_IS_ADDR_LINKLOCAL(&addr_ipv6->sin6_addr) &&
> + !IN6_IS_ADDR_MC_LINKLOCAL(&addr_ipv6->sin6_addr))) &&
> + getnameinfo(addr, addr->sa_family == AF_INET6 ?
> + sizeof(sockaddr_in6) : sizeof(sockaddr_in),
> + host, sizeof(host), nullptr, 0, 0) == 0 &&
> + strncmp(short_host_name.c_str(), host, short_host_name.size()) ==
> 0 &&
> + host[short_host_name.size()] == '.') {
> + fqdn = host;
> + break;
> + }
> + }
> + freeifaddrs(ifa);
> + } else {
> + LOG_ER("getifaddrs() failed, errno=%d", errno);
> + }
> + return fqdn;
> +}
> +
> +std::string Conf::GetNodeName(const std::string& short_host_name) {
> + std::string node_name;
> + std::ifstream str;
> + str.width(255);
> + try {
> + str.open(PKGSYSCONFDIR "/node_name");
> + str >> node_name;
> + } catch (std::ifstream::failure) {
> + node_name.clear();
> + }
> + return (str.fail() || node_name.empty()) ? short_host_name : node_name;
> +}
> +
> +std::string Conf::GetShortHostName() {
> + char short_host_name[HOST_NAME_MAX + 1];
> + if (gethostname(short_host_name, sizeof(short_host_name)) == 0) {
> + short_host_name[sizeof(short_host_name) - 1] = '\0';
> + } else {
> + LOG_ER("gethostname() failed, errno=%d", errno);
> + short_host_name[0] = '\0';
> + }
> + return short_host_name;
> +}
> +
> +} // namespace base
> diff --git a/src/base/conf.h b/src/base/conf.h
> new file mode 100644
> --- /dev/null
> +++ b/src/base/conf.h
> @@ -0,0 +1,106 @@
> +/* -*- OpenSAF -*-
> + *
> + * Copyright Ericsson AB 2017 - All Rights Reserved.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + */
> +
> +#ifndef BASE_CONF_H_
> +#define BASE_CONF_H_
> +
> +#include <pthread.h>
> +#include <cassert>
> +#include <string>
> +#include "base/macros.h"
> +#include "base/mutex.h"
> +
> +namespace base {
> +
> +class Conf {
> + public:
> + // Read the fully qualified domain name and store a copy of it in this
> class.
> + // Must be called at least once before the FullyQualifiedDomainName()
> method
> + // is called. It is harmless to call this method multiple times (though it
> + // should be avoided for performance reasons). This method is thread-safe.
> + static void InitFullyQualifiedDomainName();
> +
> + // Read the configured OpenSAF node name and store a copy of it in this
> class.
> + // Must be called at least once before the NodeName() method is called. It
> is
> + // harmless to call this method multiple times (though it should be avoided
> + // for performance reasons). This method is thread-safe.
> + static void InitNodeName();
> +
> + // Read the short host name (the host name cut at the first dot) and store
> a
> + // copy of it in this class. Must be called at least once before the
> + // ShortHostName() method is called. It is harmless to call this method
> + // multiple times (though it should be avoided for performance reasons).
> This
> + // method is thread-safe.
> + static void InitShortHostName();
> +
> + // Returns the fully qualified domain name (FQDN) of this node. An empty
> + // string is returned if the the FQDN could not be determined. Note: you
> must
> + // call InitFullyQualifiedDomainName() at least once before calling this
> + // method. This method is thread-safe.
> + static const std::string& FullyQualifiedDomainName() {
> + const Conf* i = instance();
> + assert(i->fully_qualified_domain_name_initialized_);
> + return i->fully_qualified_domain_name_;
> + }
> +
> + // Returns the configured OpenSAF node name of this node. If no name has
> been
> + // configured, or if the configuration could not be read, the short host
> name
> + // will be returned instead. If the short host name could not be determined
> + // either, an empty string is returned. Note: you must call InitNodeName()
> at
> + // least once before calling this method. This method is thread-safe.
> + static const std::string& NodeName() {
> + const Conf* i = instance();
> + assert(i->node_name_initialized_);
> + return i->node_name_;
> + }
> +
> + // Returns the short host name (the host name cut at the first dot) of this
> + // node. If the short host name could not be determined, an empty string is
> + // returned. Note: you must call InitShortHostName() at least once before
> + // calling this method. This method is thread-safe.
> + static const std::string& ShortHostName() {
> + const Conf* i = instance();
> + assert(i->short_host_name_initialized_);
> + return i->short_host_name_;
> + }
> +
> + private:
> + Conf();
> + ~Conf();
> + static const Conf* instance() {
> + return instance_;
> + }
> + static Conf* GetOrCreateInstance();
> + static void PthreadOnceInitRoutine();
> + static std::string GetFullyQualifiedDomainName(
> + const std::string& short_host_name);
> + static std::string GetNodeName(const std::string& short_host_name);
> + static std::string GetShortHostName();
> + static pthread_once_t once_control_;
> + static Conf* instance_;
> + std::string fully_qualified_domain_name_;
> + std::string node_name_;
> + std::string short_host_name_;
> + bool fully_qualified_domain_name_initialized_;
> + bool node_name_initialized_;
> + bool short_host_name_initialized_;
> + Mutex mutex_;
> +
> + DELETE_COPY_AND_MOVE_OPERATORS(Conf);
> +};
> +
> +} // namespace base
> +
> +#endif // BASE_CONF_H_
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel