resolver.c 4 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 23
#ifndef NO_THREAD
#include "thread.h"
24
#else
25 26 27 28
#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)
29 30
#endif

Jack Moffitt's avatar
Jack Moffitt committed
31 32 33 34 35 36 37 38 39
#include "resolver.h"
#include "sock.h"

/* internal function */

static int _isip(const char *what);

/* internal data */

40
#ifndef NO_THREAD
Jack Moffitt's avatar
Jack Moffitt committed
41
static mutex_t _resolver_mutex;
42
#endif
Jack Moffitt's avatar
Jack Moffitt committed
43 44
static int _initialized = 0;

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

56
    return 1;
Jack Moffitt's avatar
Jack Moffitt committed
57 58
}

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

64
    return inet_aton(what, &inp);
Jack Moffitt's avatar
Jack Moffitt committed
65
}
66
#endif
Jack Moffitt's avatar
Jack Moffitt committed
67

68 69 70

#if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO)
char *resolver_getname(const char *ip, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
71
{
72 73 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
    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
99 100


101 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
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
129 130
#else

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

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


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

187 188 189 190
    if (!_initialized)
    {
        _initialized = 1;
        thread_mutex_create (&_resolver_mutex);
Jack Moffitt's avatar
Jack Moffitt committed
191

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

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