resolver.c 3.78 KB
Newer Older
Jack Moffitt's avatar
Jack Moffitt committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
** resolver.c
**
** name resolver library
**
*/

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>

#ifndef _WIN32
14
#include <netdb.h>
15 16 17 18
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#else
19
#include <winsock2.h>
Jack Moffitt's avatar
Jack Moffitt committed
20 21
#endif

22
#include "../thread/thread.h"
Jack Moffitt's avatar
Jack Moffitt committed
23 24 25 26 27 28 29 30 31 32 33 34
#include "resolver.h"
#include "sock.h"

/* internal function */

static int _isip(const char *what);

/* internal data */

static mutex_t _resolver_mutex;
static int _initialized = 0;

35 36
#ifdef HAVE_INET_PTON
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
37
{
38 39 40 41 42 43 44
    union {
        struct in_addr v4addr;
        struct in6_addr v6addr;
    } addr_u;

    if (inet_pton(AF_INET, what, &addr_u.v4addr) <= 0)
        return inet_pton(AF_INET6, what, &addr_u.v6addr) > 0 ? 1 : 0;
Jack Moffitt's avatar
Jack Moffitt committed
45

46
    return 1;
Jack Moffitt's avatar
Jack Moffitt committed
47 48
}

49 50
#else
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
51
{
52
    struct in_addr inp;
Jack Moffitt's avatar
Jack Moffitt committed
53

54
    return inet_aton(what, &inp);
Jack Moffitt's avatar
Jack Moffitt committed
55
}
56
#endif
Jack Moffitt's avatar
Jack Moffitt committed
57

58 59 60

#if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO)
char *resolver_getname(const char *ip, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
61
{
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    struct addrinfo *head = NULL, hints;
    char *ret = NULL;

    if (!_isip(ip)) {
        strncpy(buff, ip, len);
        buff [len-1] = '\0';
        return buff;
    }

    memset (&hints, 0, sizeof (hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_CANONNAME;
    if (getaddrinfo (ip, NULL, &hints, &head))
        return NULL;

    if (head)
    {
        if (getnameinfo(head->ai_addr, head->ai_addrlen, buff, len, NULL, 
                    0, NI_NAMEREQD) == 0)
            ret = buff;

        freeaddrinfo (head);
    }

    return ret;
}
Jack Moffitt's avatar
Jack Moffitt committed
89 90


91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
char *resolver_getip(const char *name, char *buff, int len)
{
    struct addrinfo *head, hints;
    char *ret = NULL;

    if (_isip(name)) {
        strncpy(buff, name, len);
        buff [len-1] = '\0';
        return buff;
    }

    memset (&hints, 0, sizeof (hints));
    hints . ai_family = AF_UNSPEC;
    hints . ai_socktype = SOCK_STREAM;
    if (getaddrinfo (name, NULL, &hints, &head))
        return NULL;

    if (head)
    {
        if (getnameinfo(head->ai_addr, head->ai_addrlen, buff, len, NULL, 
                    0, NI_NUMERICHOST) == 0)
            ret = buff;
        freeaddrinfo (head);
    }

    return ret;
}

Jack Moffitt's avatar
Jack Moffitt committed
119 120
#else

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
char *resolver_getname(const char *ip, char *buff, int len)
{
    struct hostent *host;
    char *ret = NULL;
    struct in_addr addr;

    if (! _isip(ip))
    {
        strncpy(buff, ip, len);
        buff [len-1] = '\0';
        return buff;
    }

    thread_mutex_lock(&_resolver_mutex);
    if (inet_aton (ip, &addr)) {
        if ((host=gethostbyaddr (&addr, sizeof (struct in_addr), AF_INET)))
        {
            ret = strncpy (buff, host->h_name, len);
            buff [len-1] = '\0';
        }
    }

    thread_mutex_unlock(&_resolver_mutex);
    return ret;
Jack Moffitt's avatar
Jack Moffitt committed
145 146
}

147
char *resolver_getip(const char *name, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
148
{
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    struct hostent *host;
    char *ret = NULL;

    if (_isip(name))
    {
        strncpy(buff, name, len);
        buff [len-1] = '\0';
        return buff;
    }
    thread_mutex_lock(&_resolver_mutex);
    host = gethostbyname(name);
    if (host)
    {
        char * temp = inet_ntoa(*(struct in_addr *)host->h_addr);
        ret = strncpy(buff, temp, len);
        buff [len-1] = '\0';
    }
    thread_mutex_unlock(&_resolver_mutex);

    return ret;
}
Jack Moffitt's avatar
Jack Moffitt committed
170 171 172 173 174
#endif


void resolver_initialize()
{
175
    /* initialize the lib if we havne't done so already */
Jack Moffitt's avatar
Jack Moffitt committed
176

177 178 179 180
    if (!_initialized)
    {
        _initialized = 1;
        thread_mutex_create (&_resolver_mutex);
Jack Moffitt's avatar
Jack Moffitt committed
181

182 183 184
        /* keep dns connects (TCP) open */
#ifdef HAVE_SETHOSTENT
        sethostent(1);
Jack Moffitt's avatar
Jack Moffitt committed
185
#endif
186
    }
Jack Moffitt's avatar
Jack Moffitt committed
187 188
}

189
void resolver_shutdown(void)
Jack Moffitt's avatar
Jack Moffitt committed
190
{
191 192 193 194 195 196
    if (_initialized)
    {
        thread_mutex_destroy(&_resolver_mutex);
        _initialized = 0;
#ifdef HAVE_ENDHOSTENT
        endhostent();
Jack Moffitt's avatar
Jack Moffitt committed
197
#endif
198
    }
Jack Moffitt's avatar
Jack Moffitt committed
199 200
}