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

📄 res_send.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * ++Copyright++ 1985, 1989, 1993
 * -
 * Copyright (c) 1985, 1989, 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 Copyright (c) 1993 by Digital Equipment Corporation.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies, and that
 * the name of Digital Equipment Corporation not be used in advertising or
 * publicity pertaining to distribution of the document or software without
 * specific, written prior permission.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 * -
 * --Copyright--
 */

/*
 * 10.Dec-97   Adapted for Waterloo TCP/IP - G. Vanem (giva@bgnett.no)
 *
 */

/*
 * Send query to name server and wait for reply.
 */

#include "resolver.h"

#if defined(USE_BIND)

static sock_type *sock = NULL;  /* socket used for communications */
static int vc          = 0;     /* is the socket a virtual ciruit? */
static int connected   = 0;     /* is the socket connected */

static int  name_server_send (int ns, struct sockaddr_in *nsap);
static void resolve_close    (void);

#define SAME_NS (-1)
#define NEXT_NS (-2)


#define Dprint(cond,args) if (cond) do {  \
                             printf args; \
                           } while (0)

#define DprintQ(cond,args,query,size)                       \
                          if (cond) do {                    \
                             printf args;                   \
                             __fp_nquery(query,size,stdout);\
                          } while (0)

static void Aerror (const char *str, const char *error,
                    struct sockaddr_in address)
{
  if (_res.options & RES_DEBUG)
     fprintf (stderr, "res_send: %s (%s/%u): %s\n",
              str, inet_ntoa(address.sin_addr), ntohs(address.sin_port),
              error);
}

static void Perror (const char *str, const char *error)
{
  if (_res.options & RES_DEBUG)
     fprintf (stderr, "res_send: %s: %s\n", str, error);
}

static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;

void res_send_setqhook (res_send_qhook hook)
{
  Qhook = hook;
}

void res_send_setrhook (res_send_rhook hook)
{
  Rhook = hook;
}

/*
 * int res_isourserver(ina)
 *    looks up "ina" in _res.ns_addr_list[]
 * returns:
 *    0 : not found
 *   >0 : found
 * author:
 *    paul vixie, 29may94
 */
int res_isourserver (const struct sockaddr_in *inp)
{
  struct sockaddr_in ina = *inp;
  int    ns;

  for (ns = 0; ns < _res.nscount; ns++)
  {
    const struct sockaddr_in *srv = &_res.nsaddr_list[ns];

    if (srv->sin_family == ina.sin_family &&
        srv->sin_port   == ina.sin_port   &&
        (srv->sin_addr.s_addr == INADDR_ANY ||
         srv->sin_addr.s_addr == ina.sin_addr.s_addr))
      return (1);
  }
  return (0);
}

/*
 * int res_nameinquery(name, type, class, buf, eom)
 *    look for (name,type,class) in the query section of packet (buf,eom)
 * returns:
 *    -1 : format error
 *     0 : not found
 *    >0 : found
 * author:
 *     paul vixie, 29may94
 */
int res_nameinquery (const char *name, int type, int class,
                     const u_char *buf, const u_char *eom)
{
  const u_char *cp = buf + HFIXEDSZ;
  int   qdcount    = ntohs (((HEADER*)buf)->qdcount);

  while (qdcount-- > 0)
  {
    char tname[MAXDNAME+1];
    int n, ttype, tclass;

    n = dn_expand (buf, eom, cp, tname, sizeof tname);
    if (n < 0)
       return (-1);
    cp += n;
    ttype  = _getshort (cp);
    cp    += INT16SZ;
    tclass = _getshort (cp);
    cp    += INT16SZ;
    if (ttype == type && tclass == class && !stricmp(tname,name))
       return (1);
  }
  return (0);
}


/*
 * int res_queriesmatch(buf1, eom1, buf2, eom2)
 *    is there a 1:1 mapping of (name,type,class)
 *    in (buf1,eom1) and (buf2,eom2)?
 * returns:
 *    -1 : format error
 *     0 : not a 1:1 mapping
 *    >0 : is a 1:1 mapping
 * author:
 *     paul vixie, 29may94
 */
int res_queriesmatch (const u_char *buf1, const u_char *eom1,
                      const u_char *buf2, const u_char *eom2 )
{
  const u_char *cp = buf1 + HFIXEDSZ;
  int   qdcount    = ntohs (((HEADER*)buf1)->qdcount);

  if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
     return (0);

  while (qdcount-- > 0)
  {
    char tname[MAXDNAME+1];
    int n, ttype, tclass;

    n = dn_expand (buf1, eom1, cp, tname, sizeof tname);
    if (n < 0)
       return (-1);
    cp += n;
    ttype  = _getshort (cp);
    cp    += INT16SZ;
    tclass = _getshort (cp);
    cp    += INT16SZ;
    if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
       return (0);
  }
  return (1);
}

/*--------------------------------------------------------------------*/

static HEADER *hp, *anhp;
static int     gotsomewhere, connreset, terrno, try;
static int     v_circuit, ns, n;
static u_long  badns;
static u_char *ns_buf,   *ns_ans;
static int     ns_buflen, ns_anssiz;

int res_send (const u_char *buf, int buflen, u_char *ans, int anssiz)
{
  hp   = (HEADER *) buf;
  anhp = (HEADER *) ans;

  ns_buf    = (u_char*)buf;
  ns_ans    = ans;
  ns_buflen = buflen;
  ns_anssiz = anssiz;

  if ((_res.options & RES_INIT) == 0 && res_init() == -1)
  {
    /* errno should have been set by res_init() in this case
     */
    return (-1);
  }
  DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
           (";; res_send()\n"), buf, buflen);

  v_circuit    = (_res.options & RES_USEVC) || buflen > PACKETSZ;
  gotsomewhere = 0;
  connreset    = 0;
  terrno       = ETIMEDOUT;
  badns        = 0;

  /* Send request, RETRY times, or until successful
   */
  for (try = 0; try < _res.retry; try++)
  {
    for (ns = 0; ns < _res.nscount; ns++)
    {
      struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
      int    rc;

      do
        rc = name_server_send (ns, nsap);
      while (rc == SAME_NS);

      if (rc != NEXT_NS)
         return (rc);
    }
  }

  resolve_close();
  if (!v_circuit)
  {
    if (!gotsomewhere)
         SOCK_ERR (ECONNREFUSED); /* no nameservers found */
    else SOCK_ERR (ETIMEDOUT);    /* no answer obtained */
  }
  else
    SOCK_ERR (terrno);
  return (-1);
}

/*------------------------------------------------------------------------*/

#if defined(_MSC_VER)
  #define ERROR_TYPE int volatile /* because '&errno' is used below */
#else
  #define ERROR_TYPE int
#endif

static int tcp_conn (tcp_Socket *sock, ERROR_TYPE *error, DWORD timeout)
{
  DWORD timer  = set_timeout (timeout);
  int   status = _ip_delay0 ((sock_type*)sock, (int)timeout, NULL, NULL);

  if (status == -1)
  {
    *error = chk_timeout(timer) ? ETIMEDOUT : ECONNREFUSED;
    return (0);
  }
  *error = 0;
  return (1);
}

/*------------------------------------------------------------------------*/

static int tcp_read (tcp_Socket *sock, u_char *buf, int len,
                     ERROR_TYPE *error, DWORD timeout)
{
  int status = _ip_delay1 ((sock_type*)sock, (int)timeout, NULL, NULL);

  if (status == -1)
  {
    *error = ETIMEDOUT;
    return (0);
  }
  if (status == 1)
  {
    *error = ECONNRESET;
    return (0);
  }
  *error = 0;
  return sock_fastread ((sock_type*)sock, (BYTE*)buf, len);
}

/*------------------------------------------------------------------------*/

static int udp_read (udp_Socket *sock, u_char *buf, int len,
                     ERROR_TYPE *error, DWORD timeout)
{
  int status = _ip_delay1 ((sock_type*)sock, (int)timeout, NULL, NULL);

  if (status == -1)
  {
    *error = ETIMEDOUT;
    return (0);
  }
  *error = 0;
  return sock_fastread ((sock_type*)sock, (BYTE*)buf, len);
}

⌨️ 快捷键说明

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