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

📄 ares_process.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
    {		assert( query != 0 );		assert( channel->queries != 0 );      if (query->server == whichserver)	{	  query->skip_server[whichserver] = 1;#if 0 // !cj! - this seem to corrput memory when it is called 	  next_server(channel, query, now);#endif	}    }}static void next_server(ares_channel channel, struct query *query, time_t now){  /* Advance to the next server or try. */  query->server++;  for (; query->itry < channel->tries; query->itry++)    {      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);}/* * Same as next_server, but only attempt the next one if it's in a different network * (subnet, designated by the NIC's physical address). We don't loop around to the * beginning of the servers list since server responded with reply-code of 3 * 'No such name' * returns: *  1 - query sent *  0 - nothing happened */static int next_server_new_network(ares_channel channel, struct query *query, time_t now){  if (query->itry >= channel->tries)     return 0;  query->server++;  for (; query->server < channel->nservers; query->server++)  {    int i = 0;    struct server_state* nextToTry = &channel->servers[query->server];    if (query->skip_server[query->server])      continue;    if (nextToTry->physical_addr_len == 0)      continue;    // only try the next DNS server, nextToTry, if it hasn't been tried UP TO THIS POINT: query->server.    for (i = 0; i < query->server; i++)    {      if (   (channel->servers[i].physical_addr_len == nextToTry->physical_addr_len)          && (memcmp(nextToTry->physical_addr, channel->servers[i].physical_addr, nextToTry->physical_addr_len) == 0))      {        // we've tried this network already, try next one (query->server++).        break;      }    }    if (i == query->server)    {      ares__send_query(channel, query, now);      return 1;    }  }  return 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, query->qbuf, query->qlen, 0) == -1)	{	  query->skip_server[query->server] = 1;	  next_server(channel, query, now);	  return;	}      query->timeout = now	  + ((query->itry == 0) ? channel->timeout	     : channel->timeout << query->itry / channel->nservers);    }}static int open_tcp_socket(ares_channel channel, struct server_state *server){  int s;  struct sockaddr_in sin;#ifdef USE_IPV6  struct sockaddr_in6 sin6;#endif  /* Acquire a socket. */#ifdef USE_IPV6  assert(server->family == AF_INET || server->family == AF_INET6);  s = socket(server->family, SOCK_STREAM, 0);#else  s = socket(AF_INET, SOCK_STREAM, 0);#endif  if (s == -1)    return -1;  /* Set the socket non-blocking. */#ifdef WIN32  {	unsigned long noBlock = 1;	int errNoBlock = ioctlsocket( s, FIONBIO , &noBlock );	if ( errNoBlock != 0 )	{		return -1;	}  }#else  {	  int flags;  if (fcntl(s, F_GETFL, &flags) == -1)    {      ares__kill_socket(s);      return -1;    }  flags |= O_NONBLOCK; // Fixed evil but here - used to be &=  if (fcntl(s, F_SETFL, flags) == -1)    {      ares__kill_socket(s);      return -1;    }}#endif#ifdef WIN32#define PORTABLE_INPROGRESS_ERR WSAEWOULDBLOCK#else#define PORTABLE_INPROGRESS_ERR EINPROGRESS#endif  /* Connect to the server. */#ifdef USE_IPV6  if (server->family == AF_INET6)  {    memset(&sin6, 0, sizeof(sin6));    sin6.sin6_family = AF_INET6;    sin6.sin6_addr = server->addr6;    sin6.sin6_port = channel->tcp_port;    sin6.sin6_flowinfo = 0;    sin6.sin6_scope_id = 0;    // do i need to explicitly set the length?    if (connect(s, (const struct sockaddr *) &sin6 , sizeof(sin6)) == -1           && getErrno() != PORTABLE_INPROGRESS_ERR)    {      ares__kill_socket(s);      return -1;    }  }  else // IPv4 DNS 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 && getErrno() != PORTABLE_INPROGRESS_ERR)    {      ares__kill_socket(s);      return -1;    }  }#else  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         && getErrno() != PORTABLE_INPROGRESS_ERR)  {    ares__kill_socket(s);    return -1;  }#endif  server->tcp_socket = s;  return 0;}static int open_udp_socket(ares_channel channel, struct server_state *server){  int s;#ifdef USE_IPV6  // added by Rohan 7-Sept-2004  // should really replace sockaddr_in6 with sockaddr_storage  struct sockaddr_in6 sin6;  struct sockaddr_in sin;  /* Acquire a socket. */  assert(server->family == AF_INET || server->family == AF_INET6);  s = socket(server->family, SOCK_DGRAM, 0);#ifdef WIN32  {   	 unsigned long errNoBlock = 1;     errNoBlock = ioctlsocket( s, FIONBIO , &errNoBlock );     if ( errNoBlock != 0 )     {        return -1;     }  }#endif  if (s == -1)    return -1;  /* Connect to the server. */  if (server->family == AF_INET6)  {    memset(&sin6, 0, sizeof(sin6));    sin6.sin6_family = AF_INET6;    sin6.sin6_addr = server->addr6;    sin6.sin6_port = channel->udp_port;    sin6.sin6_flowinfo = 0;    sin6.sin6_scope_id = 0;    // do i need to explicitly set the length?    if (connect(s, (const struct sockaddr *) &sin6, sizeof(sin6)) == -1)    {      ares__kill_socket(s);      return -1;    }  }  else // IPv4 DNS 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)    {      ares__kill_socket(s);      return -1;    }  }#else  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)    {      ares__kill_socket(s);      return -1;    }#endif  if(channel->socket_function)  {     channel->socket_function(s, 1, __FILE__, __LINE__);  }      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]);    }}void ares__kill_socket(int s){#ifdef WIN32   closesocket(s);#else   close(s);#endif}

⌨️ 快捷键说明

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