ipc/chromium/src/third_party/libevent/sample/dns-example.c

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /*
michael@0 2 This example code shows how to use the high-level, low-level, and
michael@0 3 server-level interfaces of evdns.
michael@0 4
michael@0 5 XXX It's pretty ugly and should probably be cleaned up.
michael@0 6 */
michael@0 7
michael@0 8 #include <event2/event-config.h>
michael@0 9
michael@0 10 /* Compatibility for possible missing IPv6 declarations */
michael@0 11 #include "../ipv6-internal.h"
michael@0 12
michael@0 13 #include <sys/types.h>
michael@0 14
michael@0 15 #ifdef WIN32
michael@0 16 #include <winsock2.h>
michael@0 17 #include <ws2tcpip.h>
michael@0 18 #else
michael@0 19 #include <sys/socket.h>
michael@0 20 #include <netinet/in.h>
michael@0 21 #include <arpa/inet.h>
michael@0 22 #endif
michael@0 23
michael@0 24 #include <event2/event.h>
michael@0 25 #include <event2/dns.h>
michael@0 26 #include <event2/dns_struct.h>
michael@0 27 #include <event2/util.h>
michael@0 28
michael@0 29 #ifdef _EVENT_HAVE_NETINET_IN6_H
michael@0 30 #include <netinet/in6.h>
michael@0 31 #endif
michael@0 32
michael@0 33 #include <stdio.h>
michael@0 34 #include <stdlib.h>
michael@0 35 #include <string.h>
michael@0 36
michael@0 37 #define u32 ev_uint32_t
michael@0 38 #define u8 ev_uint8_t
michael@0 39
michael@0 40 static const char *
michael@0 41 debug_ntoa(u32 address)
michael@0 42 {
michael@0 43 static char buf[32];
michael@0 44 u32 a = ntohl(address);
michael@0 45 evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
michael@0 46 (int)(u8)((a>>24)&0xff),
michael@0 47 (int)(u8)((a>>16)&0xff),
michael@0 48 (int)(u8)((a>>8 )&0xff),
michael@0 49 (int)(u8)((a )&0xff));
michael@0 50 return buf;
michael@0 51 }
michael@0 52
michael@0 53 static void
michael@0 54 main_callback(int result, char type, int count, int ttl,
michael@0 55 void *addrs, void *orig) {
michael@0 56 char *n = (char*)orig;
michael@0 57 int i;
michael@0 58 for (i = 0; i < count; ++i) {
michael@0 59 if (type == DNS_IPv4_A) {
michael@0 60 printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i]));
michael@0 61 } else if (type == DNS_PTR) {
michael@0 62 printf("%s: %s\n", n, ((char**)addrs)[i]);
michael@0 63 }
michael@0 64 }
michael@0 65 if (!count) {
michael@0 66 printf("%s: No answer (%d)\n", n, result);
michael@0 67 }
michael@0 68 fflush(stdout);
michael@0 69 }
michael@0 70
michael@0 71 static void
michael@0 72 gai_callback(int err, struct evutil_addrinfo *ai, void *arg)
michael@0 73 {
michael@0 74 const char *name = arg;
michael@0 75 int i;
michael@0 76 if (err) {
michael@0 77 printf("%s: %s\n", name, evutil_gai_strerror(err));
michael@0 78 }
michael@0 79 if (ai && ai->ai_canonname)
michael@0 80 printf(" %s ==> %s\n", name, ai->ai_canonname);
michael@0 81 for (i=0; ai; ai = ai->ai_next, ++i) {
michael@0 82 char buf[128];
michael@0 83 if (ai->ai_family == PF_INET) {
michael@0 84 struct sockaddr_in *sin =
michael@0 85 (struct sockaddr_in*)ai->ai_addr;
michael@0 86 evutil_inet_ntop(AF_INET, &sin->sin_addr, buf,
michael@0 87 sizeof(buf));
michael@0 88 printf("[%d] %s: %s\n",i,name,buf);
michael@0 89 } else {
michael@0 90 struct sockaddr_in6 *sin6 =
michael@0 91 (struct sockaddr_in6*)ai->ai_addr;
michael@0 92 evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
michael@0 93 sizeof(buf));
michael@0 94 printf("[%d] %s: %s\n",i,name,buf);
michael@0 95 }
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 static void
michael@0 100 evdns_server_callback(struct evdns_server_request *req, void *data)
michael@0 101 {
michael@0 102 int i, r;
michael@0 103 (void)data;
michael@0 104 /* dummy; give 192.168.11.11 as an answer for all A questions,
michael@0 105 * give foo.bar.example.com as an answer for all PTR questions. */
michael@0 106 for (i = 0; i < req->nquestions; ++i) {
michael@0 107 u32 ans = htonl(0xc0a80b0bUL);
michael@0 108 if (req->questions[i]->type == EVDNS_TYPE_A &&
michael@0 109 req->questions[i]->dns_question_class == EVDNS_CLASS_INET) {
michael@0 110 printf(" -- replying for %s (A)\n", req->questions[i]->name);
michael@0 111 r = evdns_server_request_add_a_reply(req, req->questions[i]->name,
michael@0 112 1, &ans, 10);
michael@0 113 if (r<0)
michael@0 114 printf("eeep, didn't work.\n");
michael@0 115 } else if (req->questions[i]->type == EVDNS_TYPE_PTR &&
michael@0 116 req->questions[i]->dns_question_class == EVDNS_CLASS_INET) {
michael@0 117 printf(" -- replying for %s (PTR)\n", req->questions[i]->name);
michael@0 118 r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name,
michael@0 119 "foo.bar.example.com", 10);
michael@0 120 if (r<0)
michael@0 121 printf("ugh, no luck");
michael@0 122 } else {
michael@0 123 printf(" -- skipping %s [%d %d]\n", req->questions[i]->name,
michael@0 124 req->questions[i]->type, req->questions[i]->dns_question_class);
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 r = evdns_server_request_respond(req, 0);
michael@0 129 if (r<0)
michael@0 130 printf("eeek, couldn't send reply.\n");
michael@0 131 }
michael@0 132
michael@0 133 static int verbose = 0;
michael@0 134
michael@0 135 static void
michael@0 136 logfn(int is_warn, const char *msg) {
michael@0 137 if (!is_warn && !verbose)
michael@0 138 return;
michael@0 139 fprintf(stderr, "%s: %s\n", is_warn?"WARN":"INFO", msg);
michael@0 140 }
michael@0 141
michael@0 142 int
michael@0 143 main(int c, char **v) {
michael@0 144 int idx;
michael@0 145 int reverse = 0, servertest = 0, use_getaddrinfo = 0;
michael@0 146 struct event_base *event_base = NULL;
michael@0 147 struct evdns_base *evdns_base = NULL;
michael@0 148 const char *resolv_conf = NULL;
michael@0 149 if (c<2) {
michael@0 150 fprintf(stderr, "syntax: %s [-x] [-v] [-c resolv.conf] hostname\n", v[0]);
michael@0 151 fprintf(stderr, "syntax: %s [-servertest]\n", v[0]);
michael@0 152 return 1;
michael@0 153 }
michael@0 154 idx = 1;
michael@0 155 while (idx < c && v[idx][0] == '-') {
michael@0 156 if (!strcmp(v[idx], "-x"))
michael@0 157 reverse = 1;
michael@0 158 else if (!strcmp(v[idx], "-v"))
michael@0 159 verbose = 1;
michael@0 160 else if (!strcmp(v[idx], "-g"))
michael@0 161 use_getaddrinfo = 1;
michael@0 162 else if (!strcmp(v[idx], "-servertest"))
michael@0 163 servertest = 1;
michael@0 164 else if (!strcmp(v[idx], "-c")) {
michael@0 165 if (idx + 1 < c)
michael@0 166 resolv_conf = v[++idx];
michael@0 167 else
michael@0 168 fprintf(stderr, "-c needs an argument\n");
michael@0 169 } else
michael@0 170 fprintf(stderr, "Unknown option %s\n", v[idx]);
michael@0 171 ++idx;
michael@0 172 }
michael@0 173
michael@0 174 #ifdef WIN32
michael@0 175 {
michael@0 176 WSADATA WSAData;
michael@0 177 WSAStartup(0x101, &WSAData);
michael@0 178 }
michael@0 179 #endif
michael@0 180
michael@0 181 event_base = event_base_new();
michael@0 182 evdns_base = evdns_base_new(event_base, 0);
michael@0 183 evdns_set_log_fn(logfn);
michael@0 184
michael@0 185 if (servertest) {
michael@0 186 evutil_socket_t sock;
michael@0 187 struct sockaddr_in my_addr;
michael@0 188 sock = socket(PF_INET, SOCK_DGRAM, 0);
michael@0 189 if (sock == -1) {
michael@0 190 perror("socket");
michael@0 191 exit(1);
michael@0 192 }
michael@0 193 evutil_make_socket_nonblocking(sock);
michael@0 194 my_addr.sin_family = AF_INET;
michael@0 195 my_addr.sin_port = htons(10053);
michael@0 196 my_addr.sin_addr.s_addr = INADDR_ANY;
michael@0 197 if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
michael@0 198 perror("bind");
michael@0 199 exit(1);
michael@0 200 }
michael@0 201 evdns_add_server_port_with_base(event_base, sock, 0, evdns_server_callback, NULL);
michael@0 202 }
michael@0 203 if (idx < c) {
michael@0 204 int res;
michael@0 205 #ifdef WIN32
michael@0 206 if (resolv_conf == NULL)
michael@0 207 res = evdns_base_config_windows_nameservers(evdns_base);
michael@0 208 else
michael@0 209 #endif
michael@0 210 res = evdns_base_resolv_conf_parse(evdns_base,
michael@0 211 DNS_OPTION_NAMESERVERS,
michael@0 212 resolv_conf ? resolv_conf : "/etc/resolv.conf");
michael@0 213
michael@0 214 if (res < 0) {
michael@0 215 fprintf(stderr, "Couldn't configure nameservers");
michael@0 216 return 1;
michael@0 217 }
michael@0 218 }
michael@0 219
michael@0 220 printf("EVUTIL_AI_CANONNAME in example = %d\n", EVUTIL_AI_CANONNAME);
michael@0 221 for (; idx < c; ++idx) {
michael@0 222 if (reverse) {
michael@0 223 struct in_addr addr;
michael@0 224 if (evutil_inet_pton(AF_INET, v[idx], &addr)!=1) {
michael@0 225 fprintf(stderr, "Skipping non-IP %s\n", v[idx]);
michael@0 226 continue;
michael@0 227 }
michael@0 228 fprintf(stderr, "resolving %s...\n",v[idx]);
michael@0 229 evdns_base_resolve_reverse(evdns_base, &addr, 0, main_callback, v[idx]);
michael@0 230 } else if (use_getaddrinfo) {
michael@0 231 struct evutil_addrinfo hints;
michael@0 232 memset(&hints, 0, sizeof(hints));
michael@0 233 hints.ai_family = PF_UNSPEC;
michael@0 234 hints.ai_protocol = IPPROTO_TCP;
michael@0 235 hints.ai_flags = EVUTIL_AI_CANONNAME;
michael@0 236 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]);
michael@0 237 evdns_getaddrinfo(evdns_base, v[idx], NULL, &hints,
michael@0 238 gai_callback, v[idx]);
michael@0 239 } else {
michael@0 240 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]);
michael@0 241 evdns_base_resolve_ipv4(evdns_base, v[idx], 0, main_callback, v[idx]);
michael@0 242 }
michael@0 243 }
michael@0 244 fflush(stdout);
michael@0 245 event_base_dispatch(event_base);
michael@0 246 return 0;
michael@0 247 }
michael@0 248

mercurial