resolver.c 4.83 KB
Newer Older
Jack Moffitt's avatar
Jack Moffitt committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * resolver.c - name resolver library
 *
 * Copyright (C) 1999 the icecast team <team@icecast.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
20 21 22
#ifdef HAVE_CONFIG_H
 #include <config.h>
#endif
Jack Moffitt's avatar
Jack Moffitt committed
23 24 25 26 27 28 29

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

#ifndef _WIN32
30
#include <netdb.h>
31 32 33 34
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#else
35
#include <winsock2.h>
Jack Moffitt's avatar
Jack Moffitt committed
36 37
#endif

38
#ifndef NO_THREAD
39
#include <thread/thread.h>
40
#else
41 42 43 44
#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)
45 46
#endif

Jack Moffitt's avatar
Jack Moffitt committed
47 48 49 50 51 52 53 54 55
#include "resolver.h"
#include "sock.h"

/* internal function */

static int _isip(const char *what);

/* internal data */

56
#ifndef NO_THREAD
Jack Moffitt's avatar
Jack Moffitt committed
57
static mutex_t _resolver_mutex;
58
#endif
Jack Moffitt's avatar
Jack Moffitt committed
59 60
static int _initialized = 0;

61 62
#ifdef HAVE_INET_PTON
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
63
{
64 65 66 67 68 69 70
    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
71

72
    return 1;
Jack Moffitt's avatar
Jack Moffitt committed
73 74
}

75 76
#else
static int _isip(const char *what)
Jack Moffitt's avatar
Jack Moffitt committed
77
{
78
    struct in_addr inp;
Jack Moffitt's avatar
Jack Moffitt committed
79

80
    return inet_aton(what, &inp);
Jack Moffitt's avatar
Jack Moffitt committed
81
}
82
#endif
Jack Moffitt's avatar
Jack Moffitt committed
83

84 85 86

#if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO)
char *resolver_getname(const char *ip, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
87
{
88 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
    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
115 116


117 118 119 120 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_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
145 146
#else

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
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
171 172
}

173
char *resolver_getip(const char *name, char *buff, int len)
Jack Moffitt's avatar
Jack Moffitt committed
174
{
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
    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
196 197 198 199 200
#endif


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

203 204 205 206
    if (!_initialized)
    {
        _initialized = 1;
        thread_mutex_create (&_resolver_mutex);
Jack Moffitt's avatar
Jack Moffitt committed
207

208 209 210
        /* keep dns connects (TCP) open */
#ifdef HAVE_SETHOSTENT
        sethostent(1);
Jack Moffitt's avatar
Jack Moffitt committed
211
#endif
212
    }
Jack Moffitt's avatar
Jack Moffitt committed
213 214
}

215
void resolver_shutdown(void)
Jack Moffitt's avatar
Jack Moffitt committed
216
{
217 218 219 220 221 222
    if (_initialized)
    {
        thread_mutex_destroy(&_resolver_mutex);
        _initialized = 0;
#ifdef HAVE_ENDHOSTENT
        endhostent();
Jack Moffitt's avatar
Jack Moffitt committed
223
#endif
224
    }
Jack Moffitt's avatar
Jack Moffitt committed
225 226
}