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

📄 ares_process.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   * with SERVFAIL, NOTIMP, or REFUSED response codes.   */  if (!(channel->flags & ARES_FLAG_NOCHECKRESP))    {      if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)	{	  query->skip_server[whichserver] = 1;	  if (query->server == whichserver)	    next_server(channel, query, now);	  return;	}      if (!same_questions(query->qbuf, query->qlen, abuf, alen))	{	  if (query->server == whichserver)	    next_server(channel, query, now);	  return;	}    }  end_query(channel, query, ARES_SUCCESS, abuf, alen);}static void handle_error(ares_channel channel, int whichserver, time_t now){  struct query *query;  /* Reset communications with this server. */  ares__close_sockets(&channel->servers[whichserver]);  /* Tell all queries talking to this server to move on and not try   * this server again.   */  for (query = channel->queries; query; query = query->next)    {      if (query->server == whichserver)	{	  query->skip_server[whichserver] = 1;	  next_server(channel, query, now);	}    }}static void next_server(ares_channel channel, struct query *query, time_t now){  /* Advance to the next server or try. */  query->server++;  for (; query->try < channel->tries; query->try++)    {      for (; query->server < channel->nservers; query->server++)	{	  if (!query->skip_server[query->server])	    {	      ares__send_query(channel, query, now);	      return;	    }	}      query->server = 0;      /* Only one try if we're using TCP. */      if (query->using_tcp)	break;    }  end_query(channel, query, query->error_status, NULL, 0);}void ares__send_query(ares_channel channel, struct query *query, time_t now){  struct send_request *sendreq;  struct server_state *server;  server = &channel->servers[query->server];  if (query->using_tcp)    {      /* Make sure the TCP socket for this server is set up and queue       * a send request.       */      if (server->tcp_socket == -1)	{	  if (open_tcp_socket(channel, server) == -1)	    {	      query->skip_server[query->server] = 1;	      next_server(channel, query, now);	      return;	    }	}      sendreq = malloc(sizeof(struct send_request));      if (!sendreq)	end_query(channel, query, ARES_ENOMEM, NULL, 0);      sendreq->data = query->tcpbuf;      sendreq->len = query->tcplen;      sendreq->next = NULL;      if (server->qtail)	server->qtail->next = sendreq;      else	server->qhead = sendreq;      server->qtail = sendreq;      query->timeout = 0;    }  else    {      if (server->udp_socket == -1)	{	  if (open_udp_socket(channel, server) == -1)	    {	      query->skip_server[query->server] = 1;	      next_server(channel, query, now);	      return;	    }	}      if (send(server->udp_socket, (void *) query->qbuf, query->qlen, 0) == -1)	{	  query->skip_server[query->server] = 1;	  next_server(channel, query, now);	  return;	}      query->timeout = now	  + ((query->try == 0) ? channel->timeout	     : channel->timeout << query->try / channel->nservers);    }}static int open_tcp_socket(ares_channel channel, struct server_state *server){  int s;  struct sockaddr_in sin;  /* Acquire a socket. */  s = socket(AF_INET, SOCK_STREAM, 0);  if (s == -1)    return -1;  /* Set the socket non-blocking. */#ifdef __LWIP_SOCKETS_H__  {	  u32_t on = 1;	  if (lwip_ioctl(s, FIONBIO, &on))	  {		  close(s);		  return -1;	  }  }#else  {  int flags;  if (fcntl(s, F_GETFL, &flags) == -1)    {      close(s);      return -1;    }  flags &= O_NONBLOCK;  if (fcntl(s, F_SETFL, flags) == -1)    {      close(s);      return -1;    }  }#endif  /* Connect to the server. */  memset(&sin, 0, sizeof(sin));  sin.sin_family = AF_INET;  sin.sin_addr = server->addr;  sin.sin_port = channel->tcp_port;  if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1      && errno != EINPROGRESS)    {      close(s);      return -1;    }  server->tcp_socket = s;  return 0;}static int open_udp_socket(ares_channel channel, struct server_state *server){  int s;  struct sockaddr_in sin;  /* Acquire a socket. */  s = socket(AF_INET, SOCK_DGRAM, 0);  if (s == -1)    return -1;  /* Connect to the server. */  memset(&sin, 0, sizeof(sin));  sin.sin_family = AF_INET;  sin.sin_addr = server->addr;  sin.sin_port = channel->udp_port;  if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1)    {      close(s);      return -1;    }  server->udp_socket = s;  return 0;}static int same_questions(const unsigned char *qbuf, int qlen,			  const unsigned char *abuf, int alen){  struct {    const unsigned char *p;    int qdcount;    char *name;    int namelen;    int type;    int dnsclass;  } q, a;  int i, j;  if (qlen < HFIXEDSZ || alen < HFIXEDSZ)    return 0;  /* Extract qdcount from the request and reply buffers and compare them. */  q.qdcount = DNS_HEADER_QDCOUNT(qbuf);  a.qdcount = DNS_HEADER_QDCOUNT(abuf);  if (q.qdcount != a.qdcount)    return 0;  /* For each question in qbuf, find it in abuf. */  q.p = qbuf + HFIXEDSZ;  for (i = 0; i < q.qdcount; i++)    {      /* Decode the question in the query. */      if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen)	  != ARES_SUCCESS)	return 0;      q.p += q.namelen;      if (q.p + QFIXEDSZ > qbuf + qlen)	{	  free(q.name);	  return 0;	}      q.type = DNS_QUESTION_TYPE(q.p);      q.dnsclass = DNS_QUESTION_CLASS(q.p);      q.p += QFIXEDSZ;      /* Search for this question in the answer. */      a.p = abuf + HFIXEDSZ;      for (j = 0; j < a.qdcount; j++)	{	  /* Decode the question in the answer. */	  if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)	      != ARES_SUCCESS)	    {	      free(q.name);	      return 0;	    }	  a.p += a.namelen;	  if (a.p + QFIXEDSZ > abuf + alen)	    {	      free(q.name);	      free(a.name);	      return 0;	    }	  a.type = DNS_QUESTION_TYPE(a.p);	  a.dnsclass = DNS_QUESTION_CLASS(a.p);	  a.p += QFIXEDSZ;	  /* Compare the decoded questions. */	  if (strcasecmp(q.name, a.name) == 0 && q.type == a.type	      && q.dnsclass == a.dnsclass)	    {	      free(a.name);	      break;	    }	  free(a.name);	}      free(q.name);      if (j == a.qdcount)	return 0;    }  return 1;}static void end_query(ares_channel channel, struct query *query, int status,		      unsigned char *abuf, int alen){  struct query **q;  int i;  query->callback(query->arg, status, abuf, alen);  for (q = &channel->queries; *q; q = &(*q)->next)    {      if (*q == query)	break;    }  *q = query->next;  free(query->tcpbuf);  free(query->skip_server);  free(query);  /* Simple cleanup policy: if no queries are remaining, close all   * network sockets unless STAYOPEN is set.   */  if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))    {      for (i = 0; i < channel->nservers; i++)	ares__close_sockets(&channel->servers[i]);    }}

⌨️ 快捷键说明

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