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 + -
显示快捷键?