⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 res.c

📁 快速开发
💻 C
字号:
/* * Copyright (c) 1985, 1988, 1993 *    The Regents of the University of California.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by the University of *      California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:  * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of Silicon Graphics, Inc. nor the names of its *    contributors may be used to endorse or promote products derived from *    this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#if defined (DARWIN)#define BIND_8_COMPAT#endif#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <netdb.h>#include <errno.h>#include "st.h"#define MAXPACKET 1024#if !defined(NETDB_INTERNAL) && defined(h_NETDB_INTERNAL)#define NETDB_INTERNAL h_NETDB_INTERNAL#endif/* New in Solaris 7 */#ifdef ns_get16#define _getshort(cp) ns_get16(cp)#endiftypedef union {    HEADER hdr;    u_char buf[MAXPACKET];} querybuf_t;static int parse_answer(querybuf_t *ans, int len, struct in_addr *addr){  char buf[MAXPACKET];  HEADER *ahp;  u_char *cp, *eoa;  int type, n;  ahp = &ans->hdr;  eoa = ans->buf + len;  cp = ans->buf + sizeof(HEADER);  while (ahp->qdcount > 0) {    ahp->qdcount--;    cp += dn_skipname(cp, eoa) + QFIXEDSZ;  }  while (ahp->ancount > 0 && cp < eoa) {    ahp->ancount--;    if ((n = dn_expand(ans->buf, eoa, cp, buf, sizeof(buf))) < 0)      break;    cp += n;    type = _getshort(cp);    cp += 8;    n = _getshort(cp);    cp += 2;    if (type == T_CNAME) {      cp += n;      continue;    }    memcpy(addr, cp, n);    return 0;  }  h_errno = TRY_AGAIN;  return -1;}static int query_domain(st_netfd_t nfd, const char *name, struct in_addr *addr,			st_utime_t timeout){  querybuf_t qbuf;  u_char *buf = qbuf.buf;  HEADER *hp = &qbuf.hdr;  int blen = sizeof(qbuf);  int i, len, id;  for (i = 0; i < _res.nscount; i++) {    len = res_mkquery(QUERY, name, C_IN, T_A, NULL, 0, NULL, buf, blen);    if (len <= 0) {      h_errno = NO_RECOVERY;      return -1;    }    id = hp->id;    if (st_sendto(nfd, buf, len, (struct sockaddr *)&(_res.nsaddr_list[i]),		  sizeof(struct sockaddr), timeout) != len) {      h_errno = NETDB_INTERNAL;      /* EINTR means interrupt by other thread, NOT by a caught signal */      if (errno == EINTR)	return -1;      continue;    }    /* Wait for reply */    do {      len = st_recvfrom(nfd, buf, blen, NULL, NULL, timeout);      if (len <= 0)	break;    } while (id != hp->id);    if (len < HFIXEDSZ) {      h_errno = NETDB_INTERNAL;      if (len >= 0)	errno = EMSGSIZE;      else if (errno == EINTR)  /* see the comment above */	return -1;      continue;    }    hp->ancount = ntohs(hp->ancount);    hp->qdcount = ntohs(hp->qdcount);    if ((hp->rcode != NOERROR) || (hp->ancount == 0)) {      switch (hp->rcode) {      case NXDOMAIN:	h_errno = HOST_NOT_FOUND;	break;      case SERVFAIL:	h_errno = TRY_AGAIN;	break;      case NOERROR:	h_errno = NO_DATA;	break;      case FORMERR:      case NOTIMP:      case REFUSED:      default:	h_errno = NO_RECOVERY;      }      continue;    }    if (parse_answer(&qbuf, len, addr) == 0)      return 0;  }  return -1;}#define CLOSE_AND_RETURN(ret) \  {                           \    n = errno;                \    st_netfd_close(nfd);      \    errno = n;                \    return (ret);             \  }int dns_getaddr(const char *host, struct in_addr *addr, st_utime_t timeout){  char name[MAXDNAME], **domain;  const char *cp;  int s, n, maxlen, dots;  int trailing_dot, tried_as_is;  st_netfd_t nfd;  if ((_res.options & RES_INIT) == 0 && res_init() == -1) {    h_errno = NETDB_INTERNAL;    return -1;  }  if (_res.options & RES_USEVC) {    h_errno = NETDB_INTERNAL;    errno = ENOSYS;    return -1;  }  if (!host || *host == '\0') {    h_errno = HOST_NOT_FOUND;    return -1;  }  /* Create UDP socket */  if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {    h_errno = NETDB_INTERNAL;    return -1;  }  if ((nfd = st_netfd_open_socket(s)) == NULL) {    h_errno = NETDB_INTERNAL;    n = errno;    close(s);    errno = n;    return -1;  }  maxlen = sizeof(name) - 1;  n = 0;  dots = 0;  trailing_dot = 0;  tried_as_is = 0;  for (cp = host; *cp && n < maxlen; cp++) {    dots += (*cp == '.');    name[n++] = *cp;  }  if (name[n - 1] == '.')    trailing_dot = 1;  /*   * If there are dots in the name already, let's just give it a try   * 'as is'.  The threshold can be set with the "ndots" option.   */  if (dots >= _res.ndots) {    if (query_domain(nfd, host, addr, timeout) == 0)      CLOSE_AND_RETURN(0);    if (h_errno == NETDB_INTERNAL && errno == EINTR)      CLOSE_AND_RETURN(-1);    tried_as_is = 1;  }  /*   * We do at least one level of search if   *     - there is no dot and RES_DEFNAME is set, or   *     - there is at least one dot, there is no trailing dot,   *       and RES_DNSRCH is set.   */  if ((!dots && (_res.options & RES_DEFNAMES)) ||      (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {    name[n++] = '.';    for (domain = _res.dnsrch; *domain; domain++) {      strncpy(name + n, *domain, maxlen - n);      if (query_domain(nfd, name, addr, timeout) == 0)	CLOSE_AND_RETURN(0);      if (h_errno == NETDB_INTERNAL && errno == EINTR)	CLOSE_AND_RETURN(-1);      if (!(_res.options & RES_DNSRCH))	break;    }  }  /*   * If we have not already tried the name "as is", do that now.   * note that we do this regardless of how many dots were in the   * name or whether it ends with a dot.   */  if (!tried_as_is) {    if (query_domain(nfd, host, addr, timeout) == 0)      CLOSE_AND_RETURN(0);  }  CLOSE_AND_RETURN(-1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -