Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1106 lines (856 sloc) 29.218 kb
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #include <assert.h>
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #define CARES_STATICLIB
28 #include "ares.h"
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
29 #include "node.h"
30 #include "req_wrap.h"
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
31 #include "tree.h"
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
32 #include "uv.h"
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
33
5e4e8ec build: add android support
Linus Mårtensson authored
34 #if defined(__ANDROID__) || \
35 defined(__MINGW32__) || \
36 defined(__OpenBSD__) || \
37 defined(_MSC_VER)
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
38 # include <nameser.h>
39 #else
40 # include <arpa/nameser.h>
41 #endif
42
43
44 namespace node {
45
46 namespace cares_wrap {
47
48 using v8::Array;
49 using v8::Function;
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
50 using v8::FunctionCallbackInfo;
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
51 using v8::Handle;
52 using v8::HandleScope;
53 using v8::Integer;
54 using v8::Local;
55 using v8::Null;
56 using v8::Object;
57 using v8::Persistent;
58 using v8::String;
59 using v8::Value;
60
be2320d @ry Add binding to uv_getaddrinfo
ry authored
61
62 typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;
63
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
64 struct ares_task_t {
65 UV_HANDLE_FIELDS
66 ares_socket_t sock;
67 uv_poll_t poll_watcher;
68 RB_ENTRY(ares_task_t) node;
69 };
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
70
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
71
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
72 static Cached<String> oncomplete_sym;
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
73 static ares_channel ares_channel;
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
74 static uv_timer_t ares_timer;
75 static RB_HEAD(ares_task_list, ares_task_t) ares_tasks;
76
77
78 static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) {
79 if (a->sock < b->sock) return -1;
80 if (a->sock > b->sock) return 1;
81 return 0;
82 }
83
84
85 RB_GENERATE_STATIC(ares_task_list, ares_task_t, node, cmp_ares_tasks)
86
87
88
89 /* This is called once per second by loop->timer. It is used to constantly */
90 /* call back into c-ares for possibly processing timeouts. */
91 static void ares_timeout(uv_timer_t* handle, int status) {
92 assert(!RB_EMPTY(&ares_tasks));
93 ares_process_fd(ares_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
94 }
95
96
97 static void ares_poll_cb(uv_poll_t* watcher, int status, int events) {
98 ares_task_t* task = container_of(watcher, ares_task_t, poll_watcher);
99
100 /* Reset the idle timer */
101 uv_timer_again(&ares_timer);
102
103 if (status < 0) {
104 /* An error happened. Just pretend that the socket is both readable and */
105 /* writable. */
106 ares_process_fd(ares_channel, task->sock, task->sock);
107 return;
108 }
109
110 /* Process DNS responses */
111 ares_process_fd(ares_channel,
112 events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
113 events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
114 }
115
116
117 static void ares_poll_close_cb(uv_handle_t* watcher) {
118 ares_task_t* task = container_of(watcher, ares_task_t, poll_watcher);
119 free(task);
120 }
121
122
123 /* Allocates and returns a new ares_task_t */
124 static ares_task_t* ares_task_create(uv_loop_t* loop, ares_socket_t sock) {
4d68dae @bnoordhuis src: replace c-style casts with c++-style casts
bnoordhuis authored
125 ares_task_t* task = static_cast<ares_task_t*>(malloc(sizeof(*task)));
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
126
127 if (task == NULL) {
128 /* Out of memory. */
129 return NULL;
130 }
131
132 task->loop = loop;
133 task->sock = sock;
134
135 if (uv_poll_init_socket(loop, &task->poll_watcher, sock) < 0) {
136 /* This should never happen. */
137 free(task);
138 return NULL;
139 }
140
141 return task;
142 }
143
144
145 /* Callback from ares when socket operation is started */
4d68dae @bnoordhuis src: replace c-style casts with c++-style casts
bnoordhuis authored
146 static void ares_sockstate_cb(void* data,
147 ares_socket_t sock,
148 int read,
149 int write) {
150 uv_loop_t* loop = static_cast<uv_loop_t*>(data);
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
151 ares_task_t* task;
152
153 ares_task_t lookup_task;
154 lookup_task.sock = sock;
155 task = RB_FIND(ares_task_list, &ares_tasks, &lookup_task);
156
157 if (read || write) {
158 if (!task) {
159 /* New socket */
160
161 /* If this is the first socket then start the timer. */
4d68dae @bnoordhuis src: replace c-style casts with c++-style casts
bnoordhuis authored
162 if (!uv_is_active(reinterpret_cast<uv_handle_t*>(&ares_timer))) {
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
163 assert(RB_EMPTY(&ares_tasks));
164 uv_timer_start(&ares_timer, ares_timeout, 1000, 1000);
165 }
166
167 task = ares_task_create(loop, sock);
168 if (task == NULL) {
169 /* This should never happen unless we're out of memory or something */
170 /* is seriously wrong. The socket won't be polled, but the the query */
171 /* will eventually time out. */
172 return;
173 }
174
175 RB_INSERT(ares_task_list, &ares_tasks, task);
176 }
177
178 /* This should never fail. If it fails anyway, the query will eventually */
179 /* time out. */
180 uv_poll_start(&task->poll_watcher,
181 (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
182 ares_poll_cb);
183
184 } else {
185 /* read == 0 and write == 0 this is c-ares's way of notifying us that */
186 /* the socket is now closed. We must free the data associated with */
187 /* socket. */
188 assert(task &&
189 "When an ares socket is closed we should have a handle for it");
190
191 RB_REMOVE(ares_task_list, &ares_tasks, task);
4d68dae @bnoordhuis src: replace c-style casts with c++-style casts
bnoordhuis authored
192 uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher),
193 ares_poll_close_cb);
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
194
195 if (RB_EMPTY(&ares_tasks)) {
196 uv_timer_stop(&ares_timer);
197 }
198 }
199 }
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
200
201
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
202 static Local<Array> HostentToAddresses(struct hostent* host) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
203 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
204 Local<Array> addresses = Array::New();
205
206 char ip[INET6_ADDRSTRLEN];
207 for (int i = 0; host->h_addr_list[i]; ++i) {
208 uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
209
210 Local<String> address = String::New(ip);
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
211 addresses->Set(Integer::New(i, node_isolate), address);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
212 }
213
214 return scope.Close(addresses);
215 }
216
217
218 static Local<Array> HostentToNames(struct hostent* host) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
219 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
220 Local<Array> names = Array::New();
221
222 for (int i = 0; host->h_aliases[i]; ++i) {
223 Local<String> address = String::New(host->h_aliases[i]);
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
224 names->Set(Integer::New(i, node_isolate), address);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
225 }
226
227 return scope.Close(names);
228 }
229
230
231 static const char* AresErrnoString(int errorno) {
232 switch (errorno) {
233 #define ERRNO_CASE(e) case ARES_##e: return #e;
234 ERRNO_CASE(SUCCESS)
235 ERRNO_CASE(ENODATA)
236 ERRNO_CASE(EFORMERR)
237 ERRNO_CASE(ESERVFAIL)
238 ERRNO_CASE(ENOTFOUND)
239 ERRNO_CASE(ENOTIMP)
240 ERRNO_CASE(EREFUSED)
241 ERRNO_CASE(EBADQUERY)
242 ERRNO_CASE(EBADNAME)
243 ERRNO_CASE(EBADFAMILY)
244 ERRNO_CASE(EBADRESP)
245 ERRNO_CASE(ECONNREFUSED)
246 ERRNO_CASE(ETIMEOUT)
247 ERRNO_CASE(EOF)
248 ERRNO_CASE(EFILE)
249 ERRNO_CASE(ENOMEM)
250 ERRNO_CASE(EDESTRUCTION)
251 ERRNO_CASE(EBADSTR)
252 ERRNO_CASE(EBADFLAGS)
253 ERRNO_CASE(ENONAME)
254 ERRNO_CASE(EBADHINTS)
255 ERRNO_CASE(ENOTINITIALIZED)
256 ERRNO_CASE(ELOADIPHLPAPI)
257 ERRNO_CASE(EADDRGETNETWORKPARAMS)
258 ERRNO_CASE(ECANCELLED)
259 #undef ERRNO_CASE
260 default:
261 assert(0 && "Unhandled c-ares error");
262 return "(UNKNOWN)";
263 }
264 }
265
266
267 static void SetAresErrno(int errorno) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
268 HandleScope scope(node_isolate);
74784b6 @isaacs cares: Set process._errno, not global.errno
isaacs authored
269 Local<Value> key = String::NewSymbol("_errno");
270 Local<Value> value = String::NewSymbol(AresErrnoString(errorno));
636ca7c @bnoordhuis src: cast strong persistent handles to locals
bnoordhuis authored
271 Local<Object> process = PersistentToLocal(process_p);
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
272 process->Set(key, value);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
273 }
274
275
276 class QueryWrap {
277 public:
278 QueryWrap() {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
279 HandleScope scope(node_isolate);
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
280 persistent().Reset(node_isolate, Object::New());
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
281 }
282
f1d3ae7 @bnoordhuis cares_wrap: make destructor virtual
bnoordhuis authored
283 virtual ~QueryWrap() {
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
284 assert(!persistent().IsEmpty());
285 object()->Delete(oncomplete_sym);
286 persistent().Dispose();
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
287 }
288
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
289 void SetOnComplete(Handle<Value> oncomplete) {
290 assert(oncomplete->IsFunction());
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
291 object()->Set(oncomplete_sym, oncomplete);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
292 }
293
294 // Subclasses should implement the appropriate Send method.
295 virtual int Send(const char* name) {
296 assert(0);
13d6a1f @DrPizza Basic VC++ compatibility work.
DrPizza authored
297 return 0;
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
298 }
299
300 virtual int Send(const char* name, int family) {
301 assert(0);
13d6a1f @DrPizza Basic VC++ compatibility work.
DrPizza authored
302 return 0;
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
303 }
304
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
305 inline Persistent<Object>& persistent() {
306 return object_;
307 }
308
309 inline Local<Object> object() {
636ca7c @bnoordhuis src: cast strong persistent handles to locals
bnoordhuis authored
310 return PersistentToLocal(persistent());
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
311 }
312
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
313 protected:
314 void* GetQueryArg() {
315 return static_cast<void*>(this);
316 }
317
318 static void Callback(void *arg, int status, int timeouts,
319 unsigned char* answer_buf, int answer_len) {
5664dd2 @bnoordhuis src: use static_cast where appropriate
bnoordhuis authored
320 QueryWrap* wrap = static_cast<QueryWrap*>(arg);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
321
322 if (status != ARES_SUCCESS) {
323 wrap->ParseError(status);
324 } else {
325 wrap->Parse(answer_buf, answer_len);
326 }
327
328 delete wrap;
329 }
330
331 static void Callback(void *arg, int status, int timeouts,
332 struct hostent* host) {
5664dd2 @bnoordhuis src: use static_cast where appropriate
bnoordhuis authored
333 QueryWrap* wrap = static_cast<QueryWrap*>(arg);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
334
335 if (status != ARES_SUCCESS) {
336 wrap->ParseError(status);
337 } else {
338 wrap->Parse(host);
339 }
340
341 delete wrap;
342 }
343
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
344 void CallOnComplete(Local<Value> answer) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
345 HandleScope scope(node_isolate);
346 Local<Value> argv[2] = { Integer::New(0, node_isolate), answer };
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
347 MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
348 }
349
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
350 void CallOnComplete(Local<Value> answer, Local<Value> family) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
351 HandleScope scope(node_isolate);
352 Local<Value> argv[3] = { Integer::New(0, node_isolate), answer, family };
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
353 MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
354 }
355
356 void ParseError(int status) {
357 assert(status != ARES_SUCCESS);
358 SetAresErrno(status);
359
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
360 HandleScope scope(node_isolate);
361 Local<Value> argv[1] = { Integer::New(-1, node_isolate) };
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
362 MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
363 }
364
365 // Subclasses should implement the appropriate Parse method.
366 virtual void Parse(unsigned char* buf, int len) {
367 assert(0);
368 };
369
370 virtual void Parse(struct hostent* host) {
371 assert(0);
372 };
373
374 private:
375 Persistent<Object> object_;
376 };
377
378
379 class QueryAWrap: public QueryWrap {
380 public:
381 int Send(const char* name) {
382 ares_query(ares_channel, name, ns_c_in, ns_t_a, Callback, GetQueryArg());
383 return 0;
384 }
385
386 protected:
387 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
388 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
389
390 struct hostent* host;
391
392 int status = ares_parse_a_reply(buf, len, &host, NULL, NULL);
393 if (status != ARES_SUCCESS) {
394 this->ParseError(status);
395 return;
396 }
397
398 Local<Array> addresses = HostentToAddresses(host);
399 ares_free_hostent(host);
400
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
401 this->CallOnComplete(addresses);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
402 }
403 };
404
405
406 class QueryAaaaWrap: public QueryWrap {
407 public:
408 int Send(const char* name) {
409 ares_query(ares_channel,
410 name,
411 ns_c_in,
412 ns_t_aaaa,
413 Callback,
414 GetQueryArg());
415 return 0;
416 }
417
418 protected:
419 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
420 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
421
422 struct hostent* host;
423
424 int status = ares_parse_aaaa_reply(buf, len, &host, NULL, NULL);
425 if (status != ARES_SUCCESS) {
426 this->ParseError(status);
427 return;
428 }
429
430 Local<Array> addresses = HostentToAddresses(host);
431 ares_free_hostent(host);
432
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
433 this->CallOnComplete(addresses);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
434 }
435 };
436
437
438 class QueryCnameWrap: public QueryWrap {
439 public:
440 int Send(const char* name) {
441 ares_query(ares_channel,
442 name,
443 ns_c_in,
444 ns_t_cname,
445 Callback,
446 GetQueryArg());
447 return 0;
448 }
449
450 protected:
451 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
452 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
453
454 struct hostent* host;
455
456 int status = ares_parse_a_reply(buf, len, &host, NULL, NULL);
457 if (status != ARES_SUCCESS) {
458 this->ParseError(status);
459 return;
460 }
461
462 // A cname lookup always returns a single record but we follow the
463 // common API here.
464 Local<Array> result = Array::New(1);
465 result->Set(0, String::New(host->h_name));
466 ares_free_hostent(host);
467
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
468 this->CallOnComplete(result);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
469 }
470 };
471
472
473 class QueryMxWrap: public QueryWrap {
474 public:
475 int Send(const char* name) {
476 ares_query(ares_channel, name, ns_c_in, ns_t_mx, Callback, GetQueryArg());
477 return 0;
478 }
479
480 protected:
481 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
482 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
483
484 struct ares_mx_reply* mx_start;
485 int status = ares_parse_mx_reply(buf, len, &mx_start);
486 if (status != ARES_SUCCESS) {
487 this->ParseError(status);
488 return;
489 }
490
491 Local<Array> mx_records = Array::New();
492 Local<String> exchange_symbol = String::NewSymbol("exchange");
493 Local<String> priority_symbol = String::NewSymbol("priority");
494 int i = 0;
495 for (struct ares_mx_reply* mx_current = mx_start;
496 mx_current;
497 mx_current = mx_current->next) {
498 Local<Object> mx_record = Object::New();
499 mx_record->Set(exchange_symbol, String::New(mx_current->host));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
500 mx_record->Set(priority_symbol,
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
501 Integer::New(mx_current->priority, node_isolate));
502 mx_records->Set(Integer::New(i++, node_isolate), mx_record);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
503 }
504
505 ares_free_data(mx_start);
506
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
507 this->CallOnComplete(mx_records);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
508 }
509 };
510
511
512 class QueryNsWrap: public QueryWrap {
513 public:
514 int Send(const char* name) {
515 ares_query(ares_channel, name, ns_c_in, ns_t_ns, Callback, GetQueryArg());
516 return 0;
517 }
518
519 protected:
520 void Parse(unsigned char* buf, int len) {
521 struct hostent* host;
522
523 int status = ares_parse_ns_reply(buf, len, &host);
524 if (status != ARES_SUCCESS) {
525 this->ParseError(status);
526 return;
527 }
528
529 Local<Array> names = HostentToNames(host);
530 ares_free_hostent(host);
531
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
532 this->CallOnComplete(names);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
533 }
534 };
535
536
d9c67ae @tellnes dns: implement resolveTxt()
tellnes authored
537 class QueryTxtWrap: public QueryWrap {
538 public:
539 int Send(const char* name) {
540 ares_query(ares_channel, name, ns_c_in, ns_t_txt, Callback, GetQueryArg());
541 return 0;
542 }
543
544 protected:
545 void Parse(unsigned char* buf, int len) {
546 struct ares_txt_reply* txt_out;
547
548 int status = ares_parse_txt_reply(buf, len, &txt_out);
549 if (status != ARES_SUCCESS) {
550 this->ParseError(status);
551 return;
552 }
553
554 Local<Array> txt_records = Array::New();
555
556 struct ares_txt_reply *current = txt_out;
557 for (int i = 0; current; ++i, current = current->next) {
558 Local<String> txt = String::New(reinterpret_cast<char*>(current->txt));
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
559 txt_records->Set(Integer::New(i, node_isolate), txt);
d9c67ae @tellnes dns: implement resolveTxt()
tellnes authored
560 }
561
562 ares_free_data(txt_out);
563
564 this->CallOnComplete(txt_records);
565 }
566 };
567
568
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
569 class QuerySrvWrap: public QueryWrap {
570 public:
571 int Send(const char* name) {
572 ares_query(ares_channel,
573 name,
574 ns_c_in,
575 ns_t_srv,
576 Callback,
577 GetQueryArg());
578 return 0;
579 }
580
581 protected:
582 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
583 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
584
585 struct ares_srv_reply* srv_start;
586 int status = ares_parse_srv_reply(buf, len, &srv_start);
587 if (status != ARES_SUCCESS) {
588 this->ParseError(status);
589 return;
590 }
591
592 Local<Array> srv_records = Array::New();
72e18d7 dns_uv: match the old api better, fix tests
Bert Belder authored
593 Local<String> name_symbol = String::NewSymbol("name");
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
594 Local<String> port_symbol = String::NewSymbol("port");
595 Local<String> priority_symbol = String::NewSymbol("priority");
596 Local<String> weight_symbol = String::NewSymbol("weight");
597 int i = 0;
598 for (struct ares_srv_reply* srv_current = srv_start;
599 srv_current;
600 srv_current = srv_current->next) {
601 Local<Object> srv_record = Object::New();
72e18d7 dns_uv: match the old api better, fix tests
Bert Belder authored
602 srv_record->Set(name_symbol, String::New(srv_current->host));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
603 srv_record->Set(port_symbol,
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
604 Integer::New(srv_current->port, node_isolate));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
605 srv_record->Set(priority_symbol,
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
606 Integer::New(srv_current->priority, node_isolate));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
607 srv_record->Set(weight_symbol,
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
608 Integer::New(srv_current->weight, node_isolate));
609 srv_records->Set(Integer::New(i++, node_isolate), srv_record);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
610 }
611
612 ares_free_data(srv_start);
613
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
614 this->CallOnComplete(srv_records);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
615 }
616 };
617
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
618 class QueryNaptrWrap: public QueryWrap {
619 public:
620 int Send(const char* name) {
621 ares_query(ares_channel,
622 name,
623 ns_c_in,
624 ns_t_naptr,
625 Callback,
626 GetQueryArg());
627 return 0;
628 }
629
630 protected:
631 void Parse(unsigned char* buf, int len) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
632 HandleScope scope(node_isolate);
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
633
634 ares_naptr_reply* naptr_start;
635 int status = ares_parse_naptr_reply(buf, len, &naptr_start);
636
637 if (status != ARES_SUCCESS) {
638 this->ParseError(status);
639 return;
640 }
641
642 Local<Array> naptr_records = Array::New();
643 Local<String> flags_symbol = String::NewSymbol("flags");
644 Local<String> service_symbol = String::NewSymbol("service");
645 Local<String> regexp_symbol = String::NewSymbol("regexp");
646 Local<String> replacement_symbol = String::NewSymbol("replacement");
647 Local<String> order_symbol = String::NewSymbol("order");
648 Local<String> preference_symbol = String::NewSymbol("preference");
649
650 int i = 0;
651 for (ares_naptr_reply* naptr_current = naptr_start;
652 naptr_current;
653 naptr_current = naptr_current->next) {
654
655 Local<Object> naptr_record = Object::New();
656
657 naptr_record->Set(flags_symbol,
658 String::New(reinterpret_cast<char*>(naptr_current->flags)));
659 naptr_record->Set(service_symbol,
660 String::New(reinterpret_cast<char*>(naptr_current->service)));
661 naptr_record->Set(regexp_symbol,
662 String::New(reinterpret_cast<char*>(naptr_current->regexp)));
663 naptr_record->Set(replacement_symbol,
664 String::New(naptr_current->replacement));
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
665 naptr_record->Set(order_symbol, Integer::New(naptr_current->order,
666 node_isolate));
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
667 naptr_record->Set(preference_symbol,
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
668 Integer::New(naptr_current->preference, node_isolate));
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
669
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
670 naptr_records->Set(Integer::New(i++, node_isolate), naptr_record);
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
671 }
672
673 ares_free_data(naptr_start);
674
675 this->CallOnComplete(naptr_records);
676 }
677 };
678
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
679
680 class GetHostByAddrWrap: public QueryWrap {
681 public:
682 int Send(const char* name) {
683 int length, family;
684 char address_buffer[sizeof(struct in6_addr)];
685
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
686 if (uv_inet_pton(AF_INET, name, &address_buffer).code == UV_OK) {
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
687 length = sizeof(struct in_addr);
688 family = AF_INET;
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
689 } else if (uv_inet_pton(AF_INET6, name, &address_buffer).code == UV_OK) {
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
690 length = sizeof(struct in6_addr);
691 family = AF_INET6;
692 } else {
693 return ARES_ENOTIMP;
694 }
695
696 ares_gethostbyaddr(ares_channel,
697 address_buffer,
698 length,
699 family,
700 Callback,
701 GetQueryArg());
702 return 0;
703 }
704
705 protected:
706 void Parse(struct hostent* host) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
707 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
708
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
709 this->CallOnComplete(HostentToNames(host));
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
710 }
711 };
712
713
714 class GetHostByNameWrap: public QueryWrap {
715 public:
716 int Send(const char* name, int family) {
717 ares_gethostbyname(ares_channel, name, family, Callback, GetQueryArg());
718 return 0;
719 }
720
721 protected:
722 void Parse(struct hostent* host) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
723 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
724
725 Local<Array> addresses = HostentToAddresses(host);
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
726 Local<Integer> family = Integer::New(host->h_addrtype, node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
727
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
728 this->CallOnComplete(addresses, family);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
729 }
730 };
731
732
733 template <class Wrap>
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
734 static void Query(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
735 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
736
737 assert(!args.IsConstructCall());
738 assert(args.Length() >= 2);
739 assert(args[1]->IsFunction());
740
741 Wrap* wrap = new Wrap();
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
742 wrap->SetOnComplete(args[1]);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
743
744 // We must cache the wrap's js object here, because cares might make the
745 // callback from the wrap->Send stack. This will destroy the wrap's internal
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
746 // object reference, causing wrap->object() to return an empty handle.
747 Local<Object> object = wrap->object();
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
748
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
749 String::Utf8Value name(args[0]);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
750
751 int r = wrap->Send(*name);
752 if (r) {
753 SetAresErrno(r);
754 delete wrap;
755 } else {
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
756 args.GetReturnValue().Set(object);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
757 }
758 }
759
760
761 template <class Wrap>
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
762 static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
763 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
764
765 assert(!args.IsConstructCall());
766 assert(args.Length() >= 3);
767 assert(args[2]->IsFunction());
768
769 Wrap* wrap = new Wrap();
12798c6 @ry dns callbacks should go through MakeCallback
ry authored
770 wrap->SetOnComplete(args[2]);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
771
772 // We must cache the wrap's js object here, because cares might make the
773 // callback from the wrap->Send stack. This will destroy the wrap's internal
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
774 // object reference, causing wrap->object() to return an empty handle.
775 Local<Object> object = wrap->object();
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
776
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
777 String::Utf8Value name(args[0]);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
778 int family = args[1]->Int32Value();
779
780 int r = wrap->Send(*name, family);
781 if (r) {
782 SetAresErrno(r);
783 delete wrap;
784 } else {
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
785 args.GetReturnValue().Set(object);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
786 }
787 }
788
789
be2320d @ry Add binding to uv_getaddrinfo
ry authored
790 void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
791 HandleScope scope(node_isolate);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
792
793 GetAddrInfoReqWrap* req_wrap = (GetAddrInfoReqWrap*) req->data;
794
795 Local<Value> argv[1];
796
797 if (status) {
798 // Error
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
799 SetErrno(uv_last_error(uv_default_loop()));
6acde21 @bnoordhuis src: remove unnecessary calls to Local<T>::New()
bnoordhuis authored
800 argv[0] = Null(node_isolate);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
801 } else {
802 // Success
803 struct addrinfo *address;
804 int n = 0;
805
806 // Count the number of responses.
807 for (address = res; address; address = address->ai_next) {
808 n++;
809 }
810
811 // Create the response array.
812 Local<Array> results = Array::New(n);
813
814 char ip[INET6_ADDRSTRLEN];
815 const char *addr;
816
817 n = 0;
818
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
819 // Iterate over the IPv4 responses again this time creating javascript
be2320d @ry Add binding to uv_getaddrinfo
ry authored
820 // strings for each IP and filling the results array.
821 address = res;
822 while (address) {
823 assert(address->ai_socktype == SOCK_STREAM);
824
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
825 // Ignore random ai_family types.
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
826 if (address->ai_family == AF_INET) {
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
827 // Juggle pointers
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
828 addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
829 uv_err_t err = uv_inet_ntop(address->ai_family,
830 addr,
831 ip,
832 INET6_ADDRSTRLEN);
833 if (err.code != UV_OK)
834 continue;
be2320d @ry Add binding to uv_getaddrinfo
ry authored
835
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
836 // Create JavaScript string
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
837 Local<String> s = String::New(ip);
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
838 results->Set(n, s);
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
839 n++;
840 }
841
842 // Increment
843 address = address->ai_next;
844 }
845
846 // Iterate over the IPv6 responses putting them in the array.
847 address = res;
848 while (address) {
849 assert(address->ai_socktype == SOCK_STREAM);
850
851 // Ignore random ai_family types.
852 if (address->ai_family == AF_INET6) {
853 // Juggle pointers
854 addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
855 uv_err_t err = uv_inet_ntop(address->ai_family,
856 addr,
857 ip,
858 INET6_ADDRSTRLEN);
859 if (err.code != UV_OK)
860 continue;
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
861
862 // Create JavaScript string
acea4c4 @piscisaureus dns: use uv_inet_ntop/uv_inet_pton instead of c-ares equivalents
piscisaureus authored
863 Local<String> s = String::New(ip);
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
864 results->Set(n, s);
865 n++;
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
866 }
be2320d @ry Add binding to uv_getaddrinfo
ry authored
867
868 // Increment
869 address = address->ai_next;
870 }
871
194511f @ry Return IPv4 addresses before IPv6 addresses from getaddrinfo
ry authored
872
be2320d @ry Add binding to uv_getaddrinfo
ry authored
873 argv[0] = results;
874 }
875
876 uv_freeaddrinfo(res);
877
878 // Make the callback into JavaScript
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
879 MakeCallback(req_wrap->object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
880
881 delete req_wrap;
882 }
883
884
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
885 static void IsIP(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
886 HandleScope scope(node_isolate);
fb6377e @snoj net: More accurate IP address validation and IPv6 dotted notation.
snoj authored
887
888 String::AsciiValue ip(args[0]);
889 char address_buffer[sizeof(struct in6_addr)];
890
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
891 int rc = 0;
892 if (uv_inet_pton(AF_INET, *ip, &address_buffer).code == UV_OK)
893 rc = 4;
894 else if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK)
895 rc = 6;
fb6377e @snoj net: More accurate IP address validation and IPv6 dotted notation.
snoj authored
896
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
897 args.GetReturnValue().Set(rc);
fb6377e @snoj net: More accurate IP address validation and IPv6 dotted notation.
snoj authored
898 }
899
900
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
901 static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
902 HandleScope scope(node_isolate);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
903
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
904 String::Utf8Value hostname(args[0]);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
905
c83dda8 @ry dns.lookup uses cares_wrap::GetAddrInfo
ry authored
906 int fam = AF_UNSPEC;
907 if (args[1]->IsInt32()) {
908 switch (args[1]->Int32Value()) {
909 case 6:
910 fam = AF_INET6;
911 break;
912
913 case 4:
914 fam = AF_INET;
915 break;
916 }
be2320d @ry Add binding to uv_getaddrinfo
ry authored
917 }
918
919 GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap();
920
921 struct addrinfo hints;
922 memset(&hints, 0, sizeof(struct addrinfo));
923 hints.ai_family = fam;
924 hints.ai_socktype = SOCK_STREAM;
925
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
926 int r = uv_getaddrinfo(uv_default_loop(),
be2320d @ry Add binding to uv_getaddrinfo
ry authored
927 &req_wrap->req_,
928 AfterGetAddrInfo,
929 *hostname,
930 NULL,
931 &hints);
932 req_wrap->Dispatched();
933
934 if (r) {
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
935 SetErrno(uv_last_error(uv_default_loop()));
be2320d @ry Add binding to uv_getaddrinfo
ry authored
936 delete req_wrap;
937 } else {
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
938 args.GetReturnValue().Set(req_wrap->persistent());
be2320d @ry Add binding to uv_getaddrinfo
ry authored
939 }
940 }
941
942
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
943 static void GetServers(const FunctionCallbackInfo<Value>& args) {
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
944 HandleScope scope(node_isolate);
945
946 Local<Array> server_array = Array::New();
947
948 ares_addr_node* servers;
949
950 int r = ares_get_servers(ares_channel, &servers);
951 assert(r == ARES_SUCCESS);
952
953 ares_addr_node* cur = servers;
954
955 for (int i = 0; cur != NULL; ++i, cur = cur->next) {
956 char ip[INET6_ADDRSTRLEN];
957
958 const void* caddr = static_cast<const void*>(&cur->addr);
959 uv_err_t err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
960 assert(err.code == UV_OK);
961
962 Local<String> addr = String::New(ip);
963 server_array->Set(i, addr);
964 }
965
966 ares_free_data(servers);
967
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
968 args.GetReturnValue().Set(server_array);
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
969 }
970
971
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
972 static void SetServers(const FunctionCallbackInfo<Value>& args) {
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
973 HandleScope scope(node_isolate);
974
975 assert(args[0]->IsArray());
976
977 Local<Array> arr = Local<Array>::Cast(args[0]);
978
979 uint32_t len = arr->Length();
980
981 if (len == 0) {
982 int rv = ares_set_servers(ares_channel, NULL);
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
983 return args.GetReturnValue().Set(rv);
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
984 }
985
986 ares_addr_node* servers = new ares_addr_node[len];
987 ares_addr_node* last = NULL;
988
989 uv_err_t uv_ret;
990
991 for (uint32_t i = 0; i < len; i++) {
992 assert(arr->Get(i)->IsArray());
993
994 Local<Array> elm = Local<Array>::Cast(arr->Get(i));
995
996 assert(elm->Get(0)->Int32Value());
997 assert(elm->Get(1)->IsString());
998
999 int fam = elm->Get(0)->Int32Value();
1000 String::Utf8Value ip(elm->Get(1));
1001
1002 ares_addr_node* cur = &servers[i];
1003
1004 switch (fam) {
1005 case 4:
1006 cur->family = AF_INET;
1007 uv_ret = uv_inet_pton(AF_INET, *ip, &cur->addr);
1008 break;
1009 case 6:
1010 cur->family = AF_INET6;
1011 uv_ret = uv_inet_pton(AF_INET6, *ip, &cur->addr);
1012 break;
70a75cd @bnoordhuis cares: fix uninitialized variable warning
bnoordhuis authored
1013 default:
1014 assert(0 && "Bad address family.");
1015 abort();
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
1016 }
1017
1018 if (uv_ret.code != UV_OK)
1019 break;
1020
1021 cur->next = NULL;
1022
1023 if (last != NULL)
1024 last->next = cur;
1025
1026 last = cur;
1027 }
1028
1029 int r;
1030
1031 if (uv_ret.code == UV_OK)
1032 r = ares_set_servers(ares_channel, &servers[0]);
1033 else
1034 r = ARES_EBADSTR;
1035
1036 delete[] servers;
1037
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
1038 args.GetReturnValue().Set(r);
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
1039 }
1040
1041
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
1042 static void StrError(const FunctionCallbackInfo<Value>& args) {
1043 HandleScope scope(node_isolate);
1044 const char* errmsg = ares_strerror(args[0]->Int32Value());
1045 args.GetReturnValue().Set(String::New(errmsg));
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
1046 }
1047
1048
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1049 static void Initialize(Handle<Object> target) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
1050 HandleScope scope(node_isolate);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1051 int r;
1052
1053 r = ares_library_init(ARES_LIB_INIT_ALL);
1054 assert(r == ARES_SUCCESS);
1055
1056 struct ares_options options;
6aed61f @bnoordhuis dns, cares: don't filter NOTIMP, REFUSED, SERVFAIL
bnoordhuis authored
1057 memset(&options, 0, sizeof(options));
1058 options.flags = ARES_FLAG_NOCHECKRESP;
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
1059 options.sock_state_cb = ares_sockstate_cb;
1060 options.sock_state_cb_data = uv_default_loop();
1061
1062 /* We do the call to ares_init_option for caller. */
6aed61f @bnoordhuis dns, cares: don't filter NOTIMP, REFUSED, SERVFAIL
bnoordhuis authored
1063 r = ares_init_options(&ares_channel,
1064 &options,
1065 ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
9e55ba7 @piscisaureus dns: don't rely on libuv for c-ares integration
piscisaureus authored
1066 assert(r == ARES_SUCCESS);
1067
1068 /* Initialize the timeout timer. The timer won't be started until the */
1069 /* first socket is opened. */
1070 uv_timer_init(uv_default_loop(), &ares_timer);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1071
1072 NODE_SET_METHOD(target, "queryA", Query<QueryAWrap>);
1073 NODE_SET_METHOD(target, "queryAaaa", Query<QueryAaaaWrap>);
1074 NODE_SET_METHOD(target, "queryCname", Query<QueryCnameWrap>);
1075 NODE_SET_METHOD(target, "queryMx", Query<QueryMxWrap>);
1076 NODE_SET_METHOD(target, "queryNs", Query<QueryNsWrap>);
d9c67ae @tellnes dns: implement resolveTxt()
tellnes authored
1077 NODE_SET_METHOD(target, "queryTxt", Query<QueryTxtWrap>);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1078 NODE_SET_METHOD(target, "querySrv", Query<QuerySrvWrap>);
2ad9872 @langpavel DNS: Support NAPTR queries
langpavel authored
1079 NODE_SET_METHOD(target, "queryNaptr", Query<QueryNaptrWrap>);
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1080 NODE_SET_METHOD(target, "getHostByAddr", Query<GetHostByAddrWrap>);
1081 NODE_SET_METHOD(target, "getHostByName", QueryWithFamily<GetHostByNameWrap>);
1082
be2320d @ry Add binding to uv_getaddrinfo
ry authored
1083 NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
fb6377e @snoj net: More accurate IP address validation and IPv6 dotted notation.
snoj authored
1084 NODE_SET_METHOD(target, "isIP", IsIP);
be2320d @ry Add binding to uv_getaddrinfo
ry authored
1085
8886c6b @tjfontaine dns: add getServers and setServers
tjfontaine authored
1086 NODE_SET_METHOD(target, "strerror", StrError);
1087 NODE_SET_METHOD(target, "getServers", GetServers);
1088 NODE_SET_METHOD(target, "setServers", SetServers);
1089
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
1090 target->Set(String::NewSymbol("AF_INET"),
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
1091 Integer::New(AF_INET, node_isolate));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
1092 target->Set(String::NewSymbol("AF_INET6"),
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
1093 Integer::New(AF_INET6, node_isolate));
6573fc3 @bnoordhuis src: pass node_isolate to Integer::New
bnoordhuis authored
1094 target->Set(String::NewSymbol("AF_UNSPEC"),
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
1095 Integer::New(AF_UNSPEC, node_isolate));
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1096
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
1097 oncomplete_sym = String::New("oncomplete");
858f230 @piscisaureus Bindings for libuv-integrated c-ares
piscisaureus authored
1098 }
1099
1100
1101 } // namespace cares_wrap
1102
1103 } // namespace node
1104
cdcb111 @bnoordhuis Remove stray NODE_MODULE() semi-colons.
bnoordhuis authored
1105 NODE_MODULE(node_cares_wrap, node::cares_wrap::Initialize)
Something went wrong with that request. Please try again.