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

Reply via email to