<commit_before>/*
  Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  GlusterFS is free software; you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published
  by the Free Software Foundation; either version 3 of the License,
  or (at your option) any later version.

  GlusterFS 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.  See the GNU
  Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see
  <http://www.gnu.org/licenses/>.
*/

#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include <inttypes.h>


#include "globals.h"
#include "glusterfs.h"
#include "compat.h"
#include "dict.h"
#include "xlator.h"
#include "logging.h"
#include "timer.h"
#include "defaults.h"
#include "compat.h"
#include "compat-errno.h"
#include "statedump.h"
#include "glusterd-mem-types.h"
#include "glusterd.h"
#include "glusterd-op-sm.h"
#include "glusterd-sm.h"
#include "glusterd-utils.h"
#include "glusterd-store.h"
#include "glusterd-volgen.h"
#include "glusterd-pmap.h"

#include <sys/resource.h>
#include <inttypes.h>
#include <signal.h>
#include <sys/types.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#ifdef GF_SOLARIS_HOST_OS
#include <sys/sockio.h>
#endif

static glusterd_lock_t lock;

static int32_t
glusterd_get_lock_owner (uuid_t *uuid)
{
        uuid_copy (*uuid, lock.owner) ;
        return 0;
}

static int32_t
glusterd_set_lock_owner (uuid_t owner)
{
        uuid_copy (lock.owner, owner);
        //TODO: set timestamp
        return 0;
}

static int32_t
glusterd_unset_lock_owner (uuid_t owner)
{
        uuid_clear (lock.owner);
        //TODO: set timestamp
        return 0;
}

int32_t
glusterd_is_local_addr (char *hostname)
{
        int32_t         ret = -1;
        struct          addrinfo *result = NULL;
        struct          addrinfo *res = NULL;
        int32_t         found = 0;
        struct          ifconf buf = {0,};
        char            nodename[256] = {0,};

        if ((!strcmp (hostname, "localhost")) ||
             (!strcmp (hostname, "127.0.0.1"))) {
                found = 1;
                goto out;
        }

        ret = gethostname (nodename, 256);
        if (ret)
                goto out;

        if ((!strcmp (nodename, hostname))) {
                found = 1;
                goto out;
        }

        ret = getaddrinfo (hostname, NULL, NULL, &result);

        if (ret != 0) {
                gf_log ("", GF_LOG_ERROR, "error in getaddrinfo: %s\n",
                        gai_strerror(ret));
                goto out;
        }

        for (res = result; res != NULL; res = res->ai_next) {
                char hname[1024] = "";

                ret = getnameinfo (res->ai_addr, res->ai_addrlen, hname,
                                   NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
                if (ret)
                        goto out;

                if (!strncasecmp (hname, "127", 3)) {
                        ret = 0;
                        gf_log ("", GF_LOG_NORMAL, "local addr found");
                        found = 1;
                        break;
                }
        }

        if (!found) {
                int sd = -1;
                struct ifreq  *ifr = NULL;
                int32_t       size = 0;
                int32_t       num_req = 0;
                struct sockaddr_in sa = {0,};

                sd = socket (PF_UNIX, SOCK_DGRAM, 0);
                if (sd == -1)
                        goto out;

                buf.ifc_len = sizeof (struct ifreq);
                buf.ifc_req = GF_CALLOC (1, sizeof (struct ifreq),
                                         gf_gld_mt_ifreq);
                size = buf.ifc_len;

                ret = ioctl (sd, SIOCGIFCONF, &buf);
                if (ret) {
                        close (sd);
                        goto out;
                }

                while (size <= buf.ifc_len) {
                        size += sizeof (struct ifreq);
                        buf.ifc_len = size;
                        buf.ifc_req = GF_REALLOC (buf.ifc_req, size);
                        ret = ioctl (sd, SIOCGIFCONF, &buf);
                        if (ret) {
                                close (sd);
                                goto out;
                        }
                }

                ifr = buf.ifc_req;
                num_req = size / sizeof (struct ifreq) - 1;

                while (num_req--) {
                        char *addr = inet_ntoa ( *(struct in_addr *)
                                &ifr->ifr_addr.sa_data[sizeof(sa.sin_port)]);
                        if (!strcmp (addr, hostname)) {
                                gf_log ("", GF_LOG_DEBUG, "%s found as local",
                                        addr);
                                found = 1;
                        }
                        ifr++;
                }

                if (sd > 0)
                        close (sd);
        }




out:
        if (result)
                freeaddrinfo (result);

        if (buf.ifc_req)
                GF_FREE (buf.ifc_req);

        return !found;
}

int32_t
glusterd_lock (uuid_t   uuid)
{

        uuid_t  owner;
        char    new_owner_str[50];
        char    owner_str[50];
        int     ret = -1;

        GF_ASSERT (uuid);
        uuid_unparse (uuid, new_owner_str);

        glusterd_get_lock_owner (&owner);
<commit_msg>mgmt/glusterd: glusterd_is_local_addr implementation<commit_after>/*
  Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  GlusterFS is free software; you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published
  by the Free Software Foundation; either version 3 of the License,
  or (at your option) any later version.

  GlusterFS 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.  See the GNU
  Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see
  <http://www.gnu.org/licenses/>.
*/

#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include <inttypes.h>


#include "globals.h"
#include "glusterfs.h"
#include "compat.h"
#include "dict.h"
#include "xlator.h"
#include "logging.h"
#include "timer.h"
#include "defaults.h"
#include "compat.h"
#include "compat-errno.h"
#include "statedump.h"
#include "glusterd-mem-types.h"
#include "glusterd.h"
#include "glusterd-op-sm.h"
#include "glusterd-sm.h"
#include "glusterd-utils.h"
#include "glusterd-store.h"
#include "glusterd-volgen.h"
#include "glusterd-pmap.h"

#include <sys/resource.h>
#include <inttypes.h>
#include <signal.h>
#include <sys/types.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#ifdef GF_SOLARIS_HOST_OS
#include <sys/sockio.h>
#endif

static glusterd_lock_t lock;

static int32_t
glusterd_get_lock_owner (uuid_t *uuid)
{
        uuid_copy (*uuid, lock.owner) ;
        return 0;
}

static int32_t
glusterd_set_lock_owner (uuid_t owner)
{
        uuid_copy (lock.owner, owner);
        //TODO: set timestamp
        return 0;
}

static int32_t
glusterd_unset_lock_owner (uuid_t owner)
{
        uuid_clear (lock.owner);
        //TODO: set timestamp
        return 0;
}

gf_boolean_t
glusterd_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
{
        GF_ASSERT (sa);

        gf_boolean_t is_local = _gf_false;
        const struct in_addr *addr4 = NULL;
        const struct in6_addr *addr6 = NULL;
        uint8_t      *ap   = NULL;
        struct in6_addr loopbackaddr6 = IN6ADDR_LOOPBACK_INIT;

        switch (sa->sa_family) {
                case AF_INET:
                        addr4 = &(((struct sockaddr_in *)sa)->sin_addr);
                        ap = (uint8_t*)&addr4->s_addr;
                        if (ap[0] == 127)
                                is_local = _gf_true;
                        break;

                case AF_INET6:
                        addr6 = &(((struct sockaddr_in6 *)sa)->sin6_addr);
                        if (memcmp (addr6, &loopbackaddr6,
                                    sizeof (loopbackaddr6)) == 0)
                                is_local = _gf_true;
                        break;

                default:
                        if (hostname)
                                gf_log ("glusterd", GF_LOG_ERROR,
                                        "unknown address family %d for %s",
                                        sa->sa_family, hostname);
                        break;
        }

        return is_local;
}

int32_t
glusterd_is_local_addr (char *hostname)
{
        int32_t         ret = -1;
        struct          addrinfo *result = NULL;
        struct          addrinfo *res = NULL;
        int32_t         found = 0;
        struct          ifconf buf = {0,};
        int             sd = -1;
        struct ifreq    *ifr = NULL;
        int32_t         size = 0;
        int32_t         num_req = 0;

        ret = getaddrinfo (hostname, NULL, NULL, &result);

        if (ret != 0) {
                gf_log ("", GF_LOG_ERROR, "error in getaddrinfo: %s\n",
                        gai_strerror(ret));
                goto out;
        }

        for (res = result; res != NULL; res = res->ai_next) {
                found = glusterd_is_loopback_localhost (res->ai_addr, hostname);
                if (found)
                        goto out;
        }


        sd = socket (PF_UNIX, SOCK_DGRAM, 0);
        if (sd == -1)
                goto out;

        buf.ifc_len = sizeof (struct ifreq);
        buf.ifc_req = GF_CALLOC (1, sizeof (struct ifreq),
                                 gf_gld_mt_ifreq);
        size = buf.ifc_len;

        ret = ioctl (sd, SIOCGIFCONF, &buf);
        if (ret) {
                goto out;
        }

        while (size <= buf.ifc_len) {
                size += sizeof (struct ifreq);
                buf.ifc_len = size;
                buf.ifc_req = GF_REALLOC (buf.ifc_req, size);
                ret = ioctl (sd, SIOCGIFCONF, &buf);
                if (ret) {
                        goto out;
                }
        }

        for (res = result; res != NULL; res = res->ai_next) {
                ifr = buf.ifc_req;
                num_req = size / sizeof (struct ifreq) - 1;

                while (num_req--) {
                        if ((ifr->ifr_addr.sa_family == res->ai_addr->sa_family)
                            && (memcmp (&ifr->ifr_addr, res->ai_addr,
                                        res->ai_addrlen) == 0)) {
                                found = 1;
                                goto out;
                        }
                        ifr++;
                }
        }

out:
        if (sd >= 0)
                close (sd);

        if (result)
                freeaddrinfo (result);

        if (buf.ifc_req)
                GF_FREE (buf.ifc_req);

        if (found)
                gf_log ("glusterd", GF_LOG_DEBUG, "%s is local", hostname);
        else
                gf_log ("glusterd", GF_LOG_DEBUG, "%s is not local", hostname);

        return !found;
}

int32_t
glusterd_lock (uuid_t   uuid)
{

        uuid_t  owner;
        char    new_owner_str[50];
        char    owner_str[50];
        int     ret = -1;

        GF_ASSERT (uuid);
        uuid_unparse (uuid, new_owner_str);

        glusterd_get_lock_owner (&owner);

{'fraction_non_alphanumeric': 0.10201149425287356, 'fraction_numerical': 0.012339418526031102, 'mean_word_length': 1.4493893603808736, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1549881', 'n_tokens_mistral': 3829, 'n_tokens_neox': 3595, 'n_words': 971}