resolver.c 4.05 KB
Newer Older
Jack Moffitt's avatar
Jack Moffitt committed
1 2 3 4 5 6
/*
** resolver.c
**
** name resolver library
**
*/
7 8 9
#ifdef HAVE_CONFIG_H
 #include <config.h>
#endif
Jack Moffitt's avatar
Jack Moffitt committed
10 11 12 13 14 15 16

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

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

25
#ifndef NO_THREAD
26
#include <thread/thread.h>
27
#else
28 29 30 31
#define thread_mutex_create(x) do{}while(0)
#define thread_mutex_destroy(x) do{}while(0)
#define thread_mutex_lock(x) do{}while(0)
#define thread_mutex_unlock(x) do{}while(0)
32 33
#endif

Jack Moffitt's avatar
Jack Moffitt committed
34 35 36 37 38 39 40 41 42
#include "resolver.h"
#include "sock.h"

/* internal function */

static int _isip(const char *what);

/* internal data */

43
#ifndef NO_THREAD
Jack Moffitt's avatar
Jack Moffitt committed
44
static mutex_t _resolver_mutex;
45
#endif
Jack Moffitt's avatar
Jack Moffitt committed
46 47
static int _initialized = 0;

48 49
#ifdef HAVE_INET_PTON
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
50
{
51 52 53 54 55 56 57
    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
58

59
    return 1;
Jack Moffitt's avatar
Jack Moffitt committed
60 61
}

62 63
#else
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
64
{
65
    struct in_addr inp;
Jack Moffitt's avatar
Jack Moffitt committed
66

67
    return inet_aton(what, &inp);
Jack Moffitt's avatar
Jack Moffitt committed
68
}
69
#endif
Jack Moffitt's avatar
Jack Moffitt committed
70

71 72 73

#if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO)
char *resolver_getname(const char *ip, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
74
{
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    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
102 103


104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
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
132 133
#else

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
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
158 159
}

160
char *resolver_getip(const char *name, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
161
{
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    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
183 184 185 186 187
#endif


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

190 191 192 193
    if (!_initialized)
    {
        _initialized = 1;
        thread_mutex_create (&_resolver_mutex);
Jack Moffitt's avatar
Jack Moffitt committed
194

195 196 197
        /* keep dns connects (TCP) open */
#ifdef HAVE_SETHOSTENT
        sethostent(1);
Jack Moffitt's avatar
Jack Moffitt committed
198
#endif
199
    }
Jack Moffitt's avatar
Jack Moffitt committed
200 201
}

202
void resolver_shutdown(void)
Jack Moffitt's avatar
Jack Moffitt committed
203
{
204 205 206 207 208 209
    if (_initialized)
    {
        thread_mutex_destroy(&_resolver_mutex);
        _initialized = 0;
#ifdef HAVE_ENDHOSTENT
        endhostent();
Jack Moffitt's avatar
Jack Moffitt committed
210
#endif
211
    }
Jack Moffitt's avatar
Jack Moffitt committed
212 213
}