dns.c
上传用户:ladybrid91
上传日期:2007-01-04
资源大小:287k
文件大小:4k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** dns.c DNS (Domain Name Service) lookup routines.
  3. **
  4. ** Copyright (c) 1994-1997 Peter Eriksson <pen@signum.se>
  5. **
  6. ** This program is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** This program is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <errno.h>
  20. #include <string.h>
  21. #include <syslog.h>
  22. #define IN_DNS_C
  23. #include "phttpd.h"
  24. static void *hostname_thread(dnsinfo_t *dip)
  25. {
  26.     char *hostname = NULL;
  27.     struct hostent *hep;
  28.     void *key;
  29.     int saved_errno = 0;
  30.     
  31.     if ((key = hostcache_lookup_byaddr(&dip->sin.sin_addr, 0, &hep)) != NULL)
  32.     {
  33. if (hep && hep->h_name)
  34.     hostname = s_strdup(hep->h_name);
  35. else
  36.     saved_errno = -1;
  37.     
  38. hostcache_release(key);
  39.     }
  40.     else
  41. saved_errno = -1;
  42.     
  43.     mutex_lock(&dip->mtx);
  44.     dip->hostname = hostname;
  45.     dip->saved_errno = saved_errno;
  46.     dip->state = 1;
  47.     cond_broadcast(&dip->cv);
  48.     mutex_unlock(&dip->mtx);
  49.     return NULL;
  50. }
  51. dnsinfo_t *dns_lookup_name(struct sockaddr_in *sin)
  52. {
  53.     dnsinfo_t *dip;
  54.     
  55.     dip = s_malloc(sizeof(*dip));
  56.     
  57.     mutex_init(&dip->mtx, USYNC_THREAD, NULL);
  58.     cond_init(&dip->cv, USYNC_THREAD, NULL);
  59.     dip->address = s_strdup(inet_ntoa(sin->sin_addr));
  60.     dip->sin.sin_addr.s_addr=sin->sin_addr.s_addr;
  61.     dip->hostname = NULL;
  62.     dip->state = 0;
  63.     dip->saved_errno = 0;
  64.     if (hostname_lookups == 0)
  65.     {
  66. dip->state = 1;
  67. return dip;
  68.     }
  69.     
  70.     if (thr_create(NULL,
  71.    0,
  72.    (void *(*)(void *)) hostname_thread,
  73.    (void *) dip,
  74.    THR_DETACHED,
  75.    NULL))
  76.     {
  77. syslog(LOG_ERR, "thr_create(hostname_thread) failed: %m");
  78. s_free(dip->address);
  79. s_free(dip);
  80. return NULL;
  81.     }
  82.     return dip;
  83. }
  84. char *dns_lookup_servername(dnsinfo_t *dip)
  85. {
  86.     dip->state = 0;
  87.     dip->saved_errno = 0;
  88.     hostname_thread(dip);
  89.     return (dip->hostname);
  90. }
  91. static void *hostaddr_thread(dnsinfo_t *dip)
  92. {
  93.     struct sockaddr_in sin;
  94.     struct hostent *hep;
  95.     void *key;
  96.     int saved_errno = 0;
  97.     
  98.     if ((key = hostcache_lookup_byname(dip->hostname, 0, &hep)) != NULL)
  99.     {
  100. if (hep && hep->h_addr_list && hep->h_addr_list[0])
  101.     memcpy(&sin, hep->h_addr_list[0], sizeof(sin));
  102. else
  103.     saved_errno = -1;
  104.     
  105. hostcache_release(key);
  106.     }
  107.     else
  108. saved_errno = -1;
  109.     
  110.     mutex_lock(&dip->mtx);
  111.     
  112.     dip->sin = sin;
  113.     dip->address = s_strdup(inet_ntoa(sin.sin_addr));
  114.     dip->saved_errno = saved_errno;
  115.     dip->state = 1;
  116.     
  117.     cond_broadcast(&dip->cv);
  118.     mutex_unlock(&dip->mtx);
  119.     return NULL;
  120. }
  121. dnsinfo_t *dns_lookup_addr(char *hostname)
  122. {
  123.     dnsinfo_t *dip;
  124.     
  125.     dip = s_malloc(sizeof(*dip));
  126.     
  127.     mutex_init(&dip->mtx, USYNC_THREAD, NULL);
  128.     cond_init(&dip->cv, USYNC_THREAD, NULL);
  129.     dip->hostname = s_strdup(hostname);
  130.     memset(&dip->sin, 0, sizeof(dip->sin));
  131.     dip->state = 0;
  132.     dip->saved_errno = 0;
  133.     
  134.     if (thr_create(NULL,
  135.    0,
  136.    (void *(*)(void *)) hostaddr_thread,
  137.    (void *) dip,
  138.    THR_DETACHED,
  139.    NULL))
  140.     {
  141. syslog(LOG_ERR, "thr_create(hostaddr_thread) failed: %m");
  142. mutex_destroy(&dip->mtx);
  143. cond_destroy(&dip->cv);
  144. s_free(dip->hostname);
  145. s_free(dip);
  146. return NULL;
  147.     }
  148.     return dip;
  149. }
  150. int dns_get(dnsinfo_t *dip,
  151.     struct sockaddr_in *sin,
  152.     char **hostname,
  153.     char **address,
  154.     int *port)
  155. {
  156.     mutex_lock(&dip->mtx);
  157.     while (dip->state == 0) {
  158. cond_wait(&dip->cv, &dip->mtx);
  159.     }
  160.     mutex_unlock(&dip->mtx);
  161.     if (sin)
  162. *sin = dip->sin;
  163.     if (hostname)
  164. *hostname = dip->hostname;
  165.     if (address)
  166. *address = dip->address;
  167.     if (port)
  168. *port = ntohs(dip->sin.sin_port);
  169.     
  170.     return dip->saved_errno;
  171. }
  172. void dns_free(dnsinfo_t *dip)
  173. {
  174.     if (dip == NULL)
  175. return;
  176.     
  177.     /* Make sure the thread has terminated */
  178.     (void) dns_get(dip, NULL, NULL, NULL, NULL);
  179.     mutex_destroy(&dip->mtx);
  180.     cond_destroy(&dip->cv);
  181.     s_free(dip->hostname);
  182.     s_free(dip->address);
  183.     s_free(dip);
  184. }