ares_init.c

来自「这是国外的resip协议栈」· C语言 代码 · 共 1,170 行 · 第 1/3 页

C
1,170
字号
  n = 0;  p = str;  while (*p)    {      while (*p && !isspace((unsigned char)*p))	p++;      while (isspace((unsigned char)*p))	p++;      n++;    }  channel->domains = malloc(n * sizeof(char *));  if (!channel->domains && n)    return ARES_ENOMEM;  /* Now copy the domains. */  n = 0;  p = str;  while (*p)    {      channel->ndomains = n;      q = p;      while (*q && !isspace((unsigned char)*q))	q++;      channel->domains[n] = malloc(q - p + 1);      if (!channel->domains[n])	return ARES_ENOMEM;      memcpy(channel->domains[n], p, q - p);      channel->domains[n][q - p] = 0;      p = q;      while (isspace((unsigned char)*p))	p++;      n++;    }  channel->ndomains = n;  return ARES_SUCCESS;}static int set_options(ares_channel channel, const char *str){  const char *p, *q, *val;  p = str;  while (*p)    {      q = p;      while (*q && !isspace((unsigned char)*q))	q++;      val = try_option(p, q, "ndots:");      if (val && channel->ndots == -1)	channel->ndots = atoi(val);      val = try_option(p, q, "retrans:");      if (val && channel->timeout == -1)	channel->timeout = atoi(val);      val = try_option(p, q, "retry:");      if (val && channel->tries == -1)	channel->tries = atoi(val);      p = q;      while (isspace((unsigned char)*p))	p++;    }  return ARES_SUCCESS;}static char *try_config(char *s, char *opt){  int len;  len = strlen(opt);  if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len]))    return NULL;  s += len;  while (isspace((unsigned char)*s))    s++;  return s;}static const char *try_option(const char *p, const char *q, const char *opt){  int len;  len = strlen(opt);  return (q - p > len && strncmp(p, opt, len) == 0) ? p + len : NULL;}static int ip_addr(const char *s, int len, struct in_addr *addr){  char ipbuf[16];  /* Four octets and three periods yields at most 15 characters. */  if (len > 15)    return -1;  memcpy(ipbuf, s, len);  ipbuf[len] = 0;  addr->s_addr = inet_addr(ipbuf);  if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)    return -1;  return 0;}static void natural_mask(struct apattern *pat){  struct in_addr addr;  /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,   * but portable.   */  addr.s_addr = ntohl(pat->addr.s_addr);  /* This is out of date in the CIDR world, but some people might   * still rely on it.   */  if (IN_CLASSA(addr.s_addr))    pat->mask.s_addr = htonl(IN_CLASSA_NET);  else if (IN_CLASSB(addr.s_addr))    pat->mask.s_addr = htonl(IN_CLASSB_NET);  else    pat->mask.s_addr = htonl(IN_CLASSC_NET);}/* * Finds a V4 addr in list of servers. * return: *  index i of servers whose servers[i].addr == addr *  else -1, failed to find */static int find_server(struct server_state *servers, int nservers, struct in_addr addr){  int i = 0;  if (nservers == 0)     return -1;  for (; i < nservers; i++)    {      if (servers[i].addr.s_addr == addr.s_addr)         break;    }  return (i < nservers ? i : -1);}/* * V4. Get the physical address of the first NIC whose list of DNS servers contain 'addr'. * return: ARES_SUCCESS, etc. */static int get_physical_address(char *physicalAddr, int physicalAddrBufSz, int* physAddrLen, struct in_addr addr){#ifdef WIN32  DWORD (WINAPI * GetAdaptersAddressesProc)(ULONG, DWORD, VOID *, IP_ADAPTER_ADDRESSES *, ULONG *);  HANDLE hLib = 0;  DWORD dwRet = ERROR_BUFFER_OVERFLOW;  DWORD dwSize = 0;  IP_ADAPTER_ADDRESSES *pAdapterAddresses = 0;  int rc = ARES_ENOTFOUND;  memset(physicalAddr, '\0', physicalAddrBufSz);  *physAddrLen = 0;  hLib = LoadLibrary(TEXT("iphlpapi.dll"));  if (!hLib)    return ARES_ENOTIMP;  (void*)GetAdaptersAddressesProc = GetProcAddress(hLib, TEXT("GetAdaptersAddresses"));  if(!GetAdaptersAddressesProc)  {    rc = ARES_ENOTIMP;    goto cleanup;  }  // Getting buffer size, expects overflow error  dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, NULL, &dwSize);  assert(dwRet == ERROR_BUFFER_OVERFLOW);  if (dwRet == ERROR_BUFFER_OVERFLOW)  {    pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) LocalAlloc(LMEM_ZEROINIT, dwSize);    if (! pAdapterAddresses)    {      rc = ARES_ENOMEM;      goto cleanup;    }  }  else  {    rc = ARES_ENODATA;    goto cleanup;  }  dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, pAdapterAddresses, &dwSize);  if (dwRet != ERROR_SUCCESS)  {    rc = ARES_ENODATA;    goto cleanup;  }  {    IP_ADAPTER_ADDRESSES * AI = NULL;    for (AI = pAdapterAddresses; AI != NULL; AI = AI->Next)    {      PIP_ADAPTER_DNS_SERVER_ADDRESS dnsServers = AI->FirstDnsServerAddress;      // find 'addr' in adapter's list of dns servers.      for (; dnsServers; dnsServers = dnsServers->Next)      {        if (! dnsServers->Address.lpSockaddr)          continue;        if (dnsServers->Address.lpSockaddr->sa_family == AF_INET)        {          struct sockaddr_in sockAddr = *(struct sockaddr_in*)(dnsServers->Address.lpSockaddr);          if (memcmp(&addr, &sockAddr.sin_addr.s_addr, sizeof(struct in_addr)) == 0)          {            *physAddrLen = AI->PhysicalAddressLength;            if (*physAddrLen > physicalAddrBufSz)              *physAddrLen = physicalAddrBufSz;            memcpy(physicalAddr, &AI->PhysicalAddress[0], *physAddrLen);            rc = ARES_SUCCESS;            goto cleanup;          }        }      }    }  }  rc = ARES_ENOTFOUND;cleanup:  if (hLib)    FreeLibrary(hLib);  if (pAdapterAddresses)    LocalFree(pAdapterAddresses);  return rc;#else // WIN32  return ARES_ENOTIMP;#endif // WIN32}#define  NS_INT16SZ   2#define  NS_INADDRSZ  4#define  NS_IN6ADDRSZ 16#ifdef USE_IPV6/* int * inet_pton6(src, dst) *	convert presentation level address to network order binary form. * return: *	1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: *	(1) does not touch `dst' unless it's returning 1. *	(2) :: in a full address is silently ignored. * credit: *	inspired by Mark Andrews. * author: *	Paul Vixie, 1996. */static intinet_pton6(const char *src, u_char *dst){   static const char xdigits_l[] = "0123456789abcdef",      xdigits_u[] = "0123456789ABCDEF";   u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;   const char *xdigits, *curtok;   int ch, saw_xdigit;   u_int val;   memset((tp = tmp), '\0', NS_IN6ADDRSZ);   endp = tp + NS_IN6ADDRSZ;   colonp = NULL;   /* Leading :: requires some special handling. */   if (*src == ':')      if (*++src != ':')         return (0);   curtok = src;   saw_xdigit = 0;   val = 0;   while ((ch = *src++) != '\0') {      const char *pch;      if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)         pch = strchr((xdigits = xdigits_u), ch);      if (pch != NULL) {         val <<= 4;         val |= (pch - xdigits);         if (val > 0xffff)            return (0);         saw_xdigit = 1;         continue;      }      if (ch == ':') {         curtok = src;         if (!saw_xdigit) {            if (colonp)               return (0);            colonp = tp;            continue;         }         if (tp + NS_INT16SZ > endp)            return (0);         *tp++ = (u_char) (val >> 8) & 0xff;         *tp++ = (u_char) val & 0xff;         saw_xdigit = 0;         val = 0;         continue;      }      if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&          inet_pton4(curtok, tp) > 0) {         tp += NS_INADDRSZ;         saw_xdigit = 0;         break;	/* '\0' was seen by inet_pton4(). */      }      return (0);   }   if (saw_xdigit) {      if (tp + NS_INT16SZ > endp)         return (0);      *tp++ = (u_char) (val >> 8) & 0xff;      *tp++ = (u_char) val & 0xff;   }   if (colonp != NULL) {      /*       * Since some memmove()'s erroneously fail to handle       * overlapping regions, we'll do the shift by hand.       */      const int n = tp - colonp;      int i;      for (i = 1; i <= n; i++) {         endp[- i] = colonp[n - i];         colonp[n - i] = 0;      }      tp = endp;   }   if (tp != endp)      return (0);   memcpy(dst, tmp, NS_IN6ADDRSZ);   return (1);}#endif/* int * inet_pton4(src, dst) *	like inet_aton() but without all the hexadecimal and shorthand. * return: *	1 if `src' is a valid dotted quad, else 0. * notice: *	does not touch `dst' unless it's returning 1. * author: *	Paul Vixie, 1996. */static intinet_pton4(const char *src, u_char *dst){   static const char digits[] = "0123456789";   int saw_digit, octets, ch;   u_char tmp[NS_INADDRSZ], *tp;   saw_digit = 0;   octets = 0;   *(tp = tmp) = 0;   while ((ch = *src++) != '\0') {      const char *pch;      if ((pch = strchr(digits, ch)) != NULL) {         u_int newVal = *tp * 10 + (pch - digits);         if (newVal > 255)            return (0);         *tp = newVal;         if (! saw_digit) {            if (++octets > 4)               return (0);            saw_digit = 1;         }      } else if (ch == '.' && saw_digit) {         if (octets == 4)            return (0);         *++tp = 0;         saw_digit = 0;      } else         return (0);   }   if (octets < 4)      return (0);   memcpy(dst, tmp, NS_INADDRSZ);   return (1);}

⌨️ 快捷键说明

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