A lot of updates
This commit is contained in:
@@ -1,110 +0,0 @@
|
||||
#include <event2/dns.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int n_pending_requests = 0;
|
||||
struct event_base *base = NULL;
|
||||
|
||||
struct user_data {
|
||||
char *name; /* the name we're resolving */
|
||||
int idx; /* its position on the command line */
|
||||
};
|
||||
|
||||
void callback(int errcode, struct evutil_addrinfo *addr, void *ptr)
|
||||
{
|
||||
struct user_data *data = (user_data*) ptr;
|
||||
const char *name = data->name;
|
||||
if (errcode) {
|
||||
printf("%d. %s -> %s\n", data->idx, name, evutil_gai_strerror(errcode));
|
||||
} else {
|
||||
struct evutil_addrinfo *ai;
|
||||
printf("%d. %s", data->idx, name);
|
||||
if (addr->ai_canonname)
|
||||
printf(" [%s]", addr->ai_canonname);
|
||||
puts("");
|
||||
for (ai = addr; ai; ai = ai->ai_next) {
|
||||
char buf[128];
|
||||
const char *s = NULL;
|
||||
if (ai->ai_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
|
||||
s = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128);
|
||||
} else if (ai->ai_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
|
||||
s = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128);
|
||||
}
|
||||
if (s)
|
||||
printf(" -> %s\n", s);
|
||||
}
|
||||
evutil_freeaddrinfo(addr);
|
||||
}
|
||||
free(data->name);
|
||||
free(data);
|
||||
if (--n_pending_requests == 0)
|
||||
event_base_loopexit(base, NULL);
|
||||
}
|
||||
|
||||
/* Take a list of domain names from the command line and resolve them in
|
||||
* parallel. */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
struct evdns_base *dnsbase;
|
||||
|
||||
if (argc == 1) {
|
||||
puts("No addresses given.");
|
||||
return 0;
|
||||
}
|
||||
base = event_base_new();
|
||||
if (!base)
|
||||
return 1;
|
||||
dnsbase = evdns_base_new(base, 1);
|
||||
if (!dnsbase)
|
||||
return 2;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
struct evutil_addrinfo hints;
|
||||
struct evdns_getaddrinfo_request *req;
|
||||
struct user_data *user_data;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = EVUTIL_AI_CANONNAME;
|
||||
/* Unless we specify a socktype, we'll get at least two entries for
|
||||
* each address: one for TCP and one for UDP. That's not what we
|
||||
* want. */
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
if (!(user_data = (struct user_data*) malloc(sizeof(struct user_data)))) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
if (!(user_data->name = strdup(argv[i]))) {
|
||||
perror("strdup");
|
||||
exit(1);
|
||||
}
|
||||
user_data->idx = i;
|
||||
|
||||
++n_pending_requests;
|
||||
req = evdns_getaddrinfo(dnsbase, argv[i], "_ts3" /* no service name given */, &hints, callback, user_data);
|
||||
if (req == NULL) {
|
||||
printf(" [request for %s returned immediately]\n", argv[i]);
|
||||
/* No need to free user_data or decrement n_pending_requests; that
|
||||
* happened in the callback. */
|
||||
}
|
||||
}
|
||||
|
||||
if (n_pending_requests)
|
||||
event_base_dispatch(base);
|
||||
|
||||
evdns_base_free(dnsbase, 0);
|
||||
event_base_free(base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user