/* Perform an async dns lookup. This is host -> ip. For ip -> host, use * egg_dns_reverse(). We return a dns id that you can use to cancel the * lookup. */ int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data) { dns_query_t *q = NULL; int i, cache_id; sdprintf("egg_dns_lookup(%s, %d)", host, timeout); if (is_dotted_ip(host)) { /* If it's already an ip, we're done. */ dns_answer_t answer; answer_init(&answer); answer_add(&answer, host); callback(-1, client_data, host, answer.list); answer_free(&answer); return(-1); } /* Ok, now see if it's in our host cache. */ for (i = 0; i < nhosts; i++) { if (!egg_strcasecmp(host, hosts[i].host)) { dns_answer_t answer; answer_init(&answer); answer_add(&answer, hosts[i].ip); callback(-1, client_data, host, answer.list); answer_free(&answer); return(-1); } } cache_id = cache_find(host); if (cache_id >= 0) { shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len); callback(-1, client_data, host, cache[cache_id].answer.list); return(-1); } /* check if the query was already made */ if (find_query(host)) return(-2); /* Allocate our query struct. */ q = alloc_query(client_data, callback, host); dns_send_query(q); // /* setup a timer to detect dead ns */ // dns_create_timeout_timer(&q, host, timeout); /* Send the ipv4 query. */ return(q->id); }
/* Perform an async dns reverse lookup. This does ip -> host. For host -> ip * use egg_dns_lookup(). We return a dns id that you can use to cancel the * lookup. */ int egg_dns_reverse(const char *ip, interval_t timeout, dns_callback_t callback, void *client_data) { dns_query_t *q; int i, cache_id; sdprintf("egg_dns_reverse(%s, %d)", ip, timeout); if (!is_dotted_ip(ip)) { /* If it's not a valid ip, don't even make the request. */ callback(-1, client_data, ip, NULL); return(-1); } /* Ok, see if we have it in our host cache. */ for (i = 0; i < nhosts; i++) { if (!egg_strcasecmp(hosts[i].ip, ip)) { dns_answer_t answer; answer_init(&answer); answer_add(&answer, hosts[i].host); callback(-1, client_data, ip, answer.list); answer_free(&answer); return(-1); } } cache_id = cache_find(ip); if (cache_id >= 0) { shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len); callback(-1, client_data, ip, cache[cache_id].answer.list); return(-1); } /* check if the query was already made */ if (find_query(ip)) return(-1); q = alloc_query(client_data, callback, ip); /* We need to transform the ip address into the proper form * for reverse lookup. */ if (strchr(ip, ':')) { char temp[128] = ""; socket_ipv6_to_dots(ip, temp); sdprintf("dots: %s", temp); size_t iplen = strlen(temp) + 9 + 1; q->ip = (char *) my_calloc(1, iplen); // reverse_ip(temp, q->ip); strlcat(q->ip, temp, iplen); strlcat(q->ip, "ip6.arpa", iplen); sdprintf("reversed ipv6 ip: %s", q->ip); } else { size_t iplen = strlen(ip) + 13 + 1; q->ip = (char *) my_calloc(1, iplen); reverse_ip(ip, q->ip); strlcat(q->ip, ".in-addr.arpa", iplen); } dns_send_query(q); // /* setup timer to detect dead ns */ // dns_create_timeout_timer(&q, ip, timeout); return(q->id); }
/** * DNS: For given URL retrieves IPv4/IPv6 from DNS-server. * <p> * URL can be given in one of the following form: <ul> * <li> scheme with full path with (without) user and password * <br>(e.g. "http://*****:*****@www.host.org/url-path"); * <li> host name with url-path * <br>(e.g. "www.host.org/url-path"); * <li> nothing but host name * <br>(e.g. "www.host.org"); * </ul> * * @param fd socket descriptor * @param url the URL to be resolved * @param domain_ip In case of SUCCESS stores extracted IP. * In case of FAULT stores zeros (0.0.0.0). * @return TRUE - IP successfuly retrieved; * FALSE - error condition occurs. */ int8_t dns_get_ip(int fd, int8_t * url, uint8_t * domain_ip, uint8_t ip_version) { /* this counter is used so that we abort after 30 DNS request */ int32_t i; /* this buffer stores host name retrieved from url */ static int8_t host_name[0x100]; (* domain_ip) = 0; // Retrieve host name from URL if (!urltohost((char *) url, (char *) host_name)) { printf("\nERROR:\t\t\tBad URL!\n"); return 0; } // Reformat host name into a series of labels if (!hosttodomain((char *) host_name, (char *) dns_domain_name)) { printf("\nERROR:\t\t\tBad host name!\n"); return 0; } // Check if DNS server is presented and accessible if (dns_server_ip == 0) { printf("\nERROR:\t\t\tCan't resolve domain name " "(DNS server is not presented)!\n"); return 0; } // Use DNS-server to obtain IP if (ip_version == 6) memset(dns_result_ipv6, 0, 16); else dns_result_ip = 0; dns_error = 0; strcpy((char *) dns_domain_cname, ""); for(i = 0; i < 30; ++i) { // Use canonical name in case we obtained it if (strlen((char *) dns_domain_cname)) dns_send_query(fd, dns_domain_cname, ip_version); else dns_send_query(fd, dns_domain_name, ip_version); // setting up a timer with a timeout of one seconds set_timer(TICKS_SEC); do { receive_ether(fd); if (dns_error) return 0; // FALSE - error if ((dns_result_ip != 0) && (ip_version == 4)) { memcpy(domain_ip, &dns_result_ip, 4); return 1; // TRUE - success (domain IP retrieved) } else if ((dns_result_ipv6[0] != 0) && (ip_version == 6)) { memcpy(domain_ip, dns_result_ipv6, 16); return 1; // TRUE - success (domain IP retrieved) } } while (get_timer() > 0); } printf("\nGiving up after %d DNS requests\n", i); return 0; // FALSE - domain name wasn't retrieved }