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

📄 sres.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
    query->q_hash = query->q_id * Q_PRIME /* + query->q_i_server */;    sres_qtable_append(res->res_queries, query);  }  return query;}static inlinevoid sres_remove_query(sres_resolver_t *res, sres_query_t *q, int all){  int i;  if (q->q_hash) {    sres_qtable_remove(res->res_queries, q), q->q_hash = 0;    if (all)      for (i = 0; i <= SRES_MAX_SEARCH; i++) {	if (q->q_subqueries[i] && q->q_subqueries[i]->q_hash) {	  sres_qtable_remove(res->res_queries, q->q_subqueries[i]);	  q->q_subqueries[i]->q_hash = 0;	}      }  }}/** Remove a query from hash table and free it. */staticvoid sres_free_query(sres_resolver_t *res, sres_query_t *q){  int i;  if (q == NULL)    return;  if (q->q_hash)    sres_qtable_remove(res->res_queries, q), q->q_hash = 0;  for (i = 0; i <= SRES_MAX_SEARCH; i++) {    sres_query_t *sq;    sq = q->q_subqueries[i];    q->q_subqueries[i] = NULL;    if (sq)      sres_free_query(res, sq);    if (q->q_subanswers[i])      sres_cache_free_answers(res->res_cache, q->q_subanswers[i]);    q->q_subanswers[i] = NULL;  }   su_free(res->res_home, q);}staticsres_record_t **sres_combine_results(sres_resolver_t *res,		     sres_record_t **search_results[SRES_MAX_SEARCH + 1]){  sres_record_t **combined_result;  int i, j, found;  /* Combine the results into a single list. */  for (i = 0, found = 0; i <= SRES_MAX_SEARCH; i++)    if (search_results[i])      for (j = 0; search_results[i][j]; j++)	found++;  combined_result = su_alloc((su_home_t *)res->res_cache, 			     (found + 1) * (sizeof combined_result[0]));  if (combined_result) {    for (i = 0, found = 0; i <= SRES_MAX_SEARCH; i++)      if (search_results[i])	for (j = 0; search_results[i][j]; j++) {	  combined_result[found++] = search_results[i][j];	  search_results[i][j] = NULL;	}    combined_result[found] = NULL;    sres_sort_answers(res, combined_result);  }  for (i = 0; i <= SRES_MAX_SEARCH; i++)    if (search_results[i])      sres_free_answers(res, search_results[i]), search_results[i] = NULL;  return combined_result;}staticintsres_sockaddr2string(sres_resolver_t *res,		     char name[],		     size_t namelen,		     struct sockaddr const *addr){  name[0] = '\0';  if (addr->sa_family == AF_INET) {    struct sockaddr_in const *sin = (struct sockaddr_in *)addr;    uint8_t const *in_addr = (uint8_t*)&sin->sin_addr;    return snprintf(name, namelen, "%u.%u.%u.%u.in-addr.arpa.",		    in_addr[3], in_addr[2], in_addr[1], in_addr[0]);  }#if HAVE_SIN6  else if (addr->sa_family == AF_INET6) {    struct sockaddr_in6 const *sin6 = (struct sockaddr_in6 *)addr;    int addrsize = sizeof(sin6->sin6_addr.s6_addr);    char *postfix;    int required;    int i;    if (res->res_config->c_opt.ip6int)      postfix = "ip6.int.";    else      postfix = "ip6.arpa.";    required = addrsize * 4 + strlen(postfix);    if (namelen <= required)      return required;    for (i = 0; i < addrsize; i++) {      uint8_t byte = sin6->sin6_addr.s6_addr[addrsize - i - 1];      uint8_t hex;      hex = byte & 0xf;      name[4 * i] = hex > 9 ? hex + 'a' - 10 : hex + '0';      name[4 * i + 1] = '.';      hex = (byte >> 4) & 0xf;      name[4 * i + 2] = hex > 9 ? hex + 'a' - 10 : hex + '0';      name[4 * i + 3] = '.';    }        strcpy(name + 4 * i, postfix);    return required;  }#endif  else {    su_seterrno(EAFNOSUPPORT);    SU_DEBUG_3(("%s: %s\n", "sres_sockaddr2string",                 su_strerror(EAFNOSUPPORT)));    return 0;  }}/** Make a domain name a top level domain name. * * The function sres_toplevel() returns a copies string @a domain and  * terminates it with a dot if it is not already terminated.  */staticchar const *sres_toplevel(char buf[], size_t blen, char const *domain){  size_t len;  int already;  if (!domain)    return su_seterrno(EFAULT), (void *)NULL;  len = strlen(domain);  if (len >= blen)    return su_seterrno(ENAMETOOLONG), (void *)NULL;  already = len > 0 && domain[len - 1] == '.';  if (already)    return domain;  if (len + 1 >= blen)    return su_seterrno(ENAMETOOLONG), (void *)NULL;  strcpy(buf, domain);  buf[len] = '.'; buf[len + 1] = '\0';  return buf;}/* ---------------------------------------------------------------------- */static int sres_parse_config(sres_config_t *, FILE *);static int sres_parse_options(sres_config_t *c, char const *value);static int sres_parse_nameserver(sres_config_t *c, char const *server);static time_t sres_config_timestamp(sres_config_t const *c);/** Update configuration * */int sres_resolver_update(sres_resolver_t *res, int always){  sres_config_t *c = NULL;  sres_config_t const *previous;  sres_server_t **servers, **old_servers;  previous = res->res_config;  time(&res->res_now);  if (!always && previous && res->res_now < res->res_checked)    return 0;  /* Try avoid checking for changes too often. */  res->res_checked = res->res_now + SRES_UPDATE_INTERVAL_SECS;     if (!always && previous &&       sres_config_timestamp(previous) == previous->c_modified)    return 0;  c = sres_parse_resolv_conf(res, res->res_options);  if (!c)    return -1;  res->res_config = c;  if (sres_config_changed_servers(c, previous)) {    servers = sres_servers_new(res, c);    if (!servers) {      su_home_unref((void *)c->c_home);      return -1;    }    old_servers = res->res_servers;    res->res_i_server = 0;    res->res_n_servers = sres_servers_count(servers);    res->res_servers = servers;    sres_servers_unref(res, old_servers);  }  su_home_unref((su_home_t *)previous->c_home);  return 0;}#if _WIN32/** Number of octets to read from a registry key at a time */#define QUERY_DATALEN         1024#define MAX_DATALEN           65535/** * Parses name servers listed in registry key 'key+lpValueName'. The * key is expected to contain a whitespace separate list of * name server IP addresses. * * @return number of server addresses added */ static int sres_parse_win32_reg_parse_dnsserver(sres_config_t *c, HKEY key, LPCTSTR lpValueName){  su_home_t *home = c->c_home;  su_strlst_t *reg_dns_list;  char *name_servers = su_alloc(home, QUERY_DATALEN);  int name_servers_length = QUERY_DATALEN;  int ret, servers_added = 0;  /* get name servers and ... */  while((ret = RegQueryValueEx(key, 			       lpValueName, 			       NULL, NULL, 			       name_servers, 			       &name_servers_length)) == ERROR_MORE_DATA) {    name_servers_length += QUERY_DATALEN;    /* sanity check, upper limit for memallocs */    if (name_servers_length > MAX_DATALEN) break;    name_servers = su_realloc(home, name_servers, name_servers_length);  }  /* if reading the key was succesful, continue */  if (ret == ERROR_SUCCESS) {    if (name_servers[0]){      int i;      /* add to list */      reg_dns_list = su_strlst_split(home, name_servers, " ");	          for(i = 0 ; i < su_strlst_len(reg_dns_list); i++) {	const char *item = su_strlst_item(reg_dns_list, i);	SU_DEBUG_3(("Adding nameserver: %s (key=%s)\n", item, (char*)lpValueName));	sres_parse_nameserver(c, item);	++servers_added;      }	          su_strlst_destroy(reg_dns_list);    }  }  su_free(home, name_servers);  return servers_added;}#endif /* _WIN32 *//** * Discover system nameservers from Windows registry. * * Refs: *  - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regqueryvalueex.asp *  - http://support.microsoft.com/default.aspx?scid=kb;en-us;120642 *  - http://support.microsoft.com/kb/314053/EN-US/ */static int sres_parse_win32_reg(sres_config_t *c){  int ret = -1;#ifdef _WIN32#define MAX_KEY_LEN           255#define MAX_VALUE_NAME_LEN    16383  su_home_t *home = c->c_home;  HKEY key_handle, interface_key_handle;    FILETIME ftime;  int index, i, found = 0;  char *interface_guid = su_alloc(home, MAX_VALUE_NAME_LEN);  int guid_size = MAX_VALUE_NAME_LEN;  /* step 1: find interface specific nameservers */  /* open the 'Interfaces' registry Key */  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 		   "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", 		   0, KEY_READ, &key_handle)) {    SU_DEBUG_2(("RegOpenKeyEx failed\n"));  } else {    index = 0;    /* for each interface listed ... */    while (RegEnumKeyEx(key_handle, index,			interface_guid, &guid_size,			NULL,NULL,0,&ftime) == ERROR_SUCCESS){      if (RegOpenKeyEx(key_handle, interface_guid,		       0, KEY_READ, 		       &interface_key_handle) == ERROR_SUCCESS) {	/* note: 'NameServer' is preferred over 'DhcpNameServer' */	found += sres_parse_win32_reg_parse_dnsserver(c, interface_key_handle, "NameServer");	if (found == 0) 	  found += sres_parse_win32_reg_parse_dnsserver(c, interface_key_handle, "DhcpNameServer");	RegCloseKey(interface_key_handle);      } else{	SU_DEBUG_2(("interface RegOpenKeyEx failed\n"));      }      index++;      guid_size = 64;    }    RegCloseKey(key_handle);  }  /* step 2: if no interface-specific nameservers are found,    *         check for system-wide nameservers */  if (found == 0) {    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 		     "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 		     0, KEY_READ, &key_handle)) {      SU_DEBUG_2(("RegOpenKeyEx failed (2)\n"));    } else {      found += sres_parse_win32_reg_parse_dnsserver(c, key_handle, "NameServer");      if (found == 0) 	found += sres_parse_win32_reg_parse_dnsserver(c, key_handle, "DhcpNameServer");      RegCloseKey(key_handle);    }  }  SU_DEBUG_3(("Total of %d name servers found from win32 registry.\n", found));  /* return success if servers found */  if (found) ret = 0;  su_free(home, interface_guid);#endif /* _WIN32 */  return ret;}/** Parse /etc/resolv.conf file. * * @retval #sres_config_t structure when successful  * @retval NULL upon an error * * @todo The resolv.conf directives @b sortlist and most of the options  *       are currently ignored. */static sres_config_t *sres_parse_resolv_conf(sres_resolver_t *res,				      char const **options){  sres_config_t *c = su_home_clone(res->res_home, (sizeof *c));  if (c) {    FILE *f;    int i, success = 0;        f = fopen(c->c_filename = res->res_cnffile, "r");    sres_parse_config(c, f);    if (f)      fclose(f);        /* on win32, query the registry for nameservers */    if (sres_parse_win32_reg(c) == 0)       ++success;#ifndef _WIN32    /* note: no 127.0.0.1 on win32 systems */    if (c->c_nameservers[0] == NULL)      sres_parse_nameserver(c, "127.0.0.1");#endif          for (i = 0; c->c_nameservers[i] && i < SRES_MAX_NAMESERVERS; i++) {      struct sockaddr_in *sin = (void *)c->c_nameservers[i]->ns_addr;      sin->sin_port = htons(c->c_port);    }    sres_parse_options(c, getenv("RES_OPTIONS"));        if (options)      for (i = 0; options[i]; i++)	sres_parse_options(c, options[i]);    sres_parse_options(c, getenv("SRES_OPTIONS"));    su_home_threadsafe(c->c_home);  }  return c;}/** Parse config file.  * * @return Number of search domains, if successful. * @retval -1 upon an error (never happens). */staticint sres_parse_config(sres_config_t *c, FILE *f){  su_home_t *home = c->c_home;  int line;  char const *localdomain;  char *search = NULL, *domain = NULL;  char buf[1025];  int i = 0;  localdomain = getenv("LOCALDOMAIN");  /* Default values */  c->c_opt.ndots = 1;  c->c_opt.check_names = 1;  c->c_opt.timeout = SRES_RETRY_INTERVAL;  c->c_opt.attempts = SRES_MAX_RETRY_COUNT;  c->c_port = 53;  if (f != NULL) {      for (line = 1; fgets(buf, sizeof(buf), f); line++) {      int len;      char *value, *b;      /* Skip whitespace at the beginning ...*/      b = buf + strspn(buf, " \t");      /* ... and at the end of line */      for (len = strlen(b); len > 0 && strchr(" \t\r\n", b[len - 1]); len--)	;      if (len == 0 || b[0] == '#') 	/* Empty line or comment */	continue;      b[len] = '\0';      len = strcspn(b, " \t");      value = b + len; value += strspn(value, " \t");#define MATCH(token) (len == strlen(token) && strncasecmp(token, b, len) == 0)      if (MATCH("nameserver")) {	if (sres_parse_nameserver(c, value) < 0)	  return -1;      }      else if (MATCH("domain")) {	if (localdomain)	/* LOCALDOMAIN overrides */	  continue;	if (search)	  su_free(home, search), search = NULL;	if (domain)	  su_free(home, domain), domain = NULL;	domain = su_strdup(home, value);	if (!domain)	  return -1;

⌨️ 快捷键说明

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