/* * resolver.c - name resolver library * * Copyright (C) 2014 Michael Smith , * Brendan Cully , * Karl Heyes , * Jack Moffitt , * Copyright (C) 2012-2018 Philipp "ph3-der-loewe" Schafft * * 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 Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifndef _WIN32 #include #include #include #include #else #include #endif #include #include #include /* internal function */ static int _isip(const char *what); /* internal data */ static igloo_mutex_t igloo__resolver_mutex; static int igloo__initialized = 0; #ifdef HAVE_INET_PTON static int _isip(const char *what) { 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; return 1; } #else static int _isip(const char *what) { struct in_addr inp; return inet_aton(what, &inp); } #endif #if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO) char *igloo_resolver_getname(const char *ip, char *buff, int len) { 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; } char *igloo_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; } #else char *igloo_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; } igloo_thread_mutex_lock(&igloo__resolver_mutex); if (inet_aton (ip, &addr)) { /* casting &addr to const char* as it is recommended on win* */ if ((host=gethostbyaddr ((const char *)&addr, sizeof (struct in_addr), AF_INET))) { ret = strncpy (buff, host->h_name, len); buff [len-1] = '\0'; } } igloo_thread_mutex_unlock(&igloo__resolver_mutex); return ret; } char *igloo_resolver_getip(const char *name, char *buff, int len) { struct hostent *host; char *ret = NULL; if (_isip(name)) { strncpy(buff, name, len); buff [len-1] = '\0'; return buff; } igloo_thread_mutex_lock(&igloo__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'; } igloo_thread_mutex_unlock(&igloo__resolver_mutex); return ret; } #endif void igloo_resolver_initialize() { /* initialize the lib if we havne't done so already */ if (!igloo__initialized) { igloo__initialized = 1; igloo_thread_mutex_create (&igloo__resolver_mutex); /* keep dns connects (TCP) open */ #ifdef HAVE_SETHOSTENT sethostent(1); #endif } } void igloo_resolver_shutdown(void) { if (igloo__initialized) { igloo_thread_mutex_destroy(&igloo__resolver_mutex); igloo__initialized = 0; #ifdef HAVE_ENDHOSTENT endhostent(); #endif } }