newer PHP version only accept real resources in userland
[m6w6/ext-ares] / php_ares.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: ares |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2006, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "php.h"
20 #include "php_ini.h"
21 #include "php_streams.h"
22 #include "ext/standard/info.h"
23 #include "php_ares.h"
24
25 #include <ares.h>
26 #ifdef HAVE_ARES_VERSION
27 # include <ares_version.h>
28 #endif
29 #ifdef HAVE_NETDB_H
30 # include <netdb.h>
31 #endif
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 #ifdef HAVE_ARPA_INET_H
36 # include <arpa/inet.h>
37 #endif
38 #ifdef HAVE_ARPA_NAMESER_H
39 # include <arpa/nameser.h>
40 #endif
41 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42 # include <arpa/nameser_compat.h>
43 #endif
44
45 #define local static inline
46
47 #ifndef ZEND_ENGINE_2
48 # define PHP_ARES_IS_CALLABLE(a,b,c) 1
49 # ifndef ZTS
50 # undef TSRMLS_SET_CTX
51 # define TSRMLS_SET_CTX
52 # undef TSRMLS_FETCH_FROM_CTX
53 # define TSRMLS_FETCH_FROM_CTX
54 # endif
55 #endif
56 #if (PHP_MAJOR_VERSION > 5) || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3))
57 # define ADDREF(z) Z_ADDREF_P(z)
58 # define PHP_ARES_IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c) TSRMLS_CC)
59 #else
60 # define ADDREF(z) ZVAL_ADDREF(z)
61 # define PHP_ARES_IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
62 #endif
63
64 #define PHP_ARES_LE_NAME "AsyncResolver"
65 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
66 static int le_ares;
67 static int le_ares_query;
68
69 static const char *php_ares_C_names[] = {
70 "INVALID",
71 "IN",
72 "C2"
73 "CHAOS",
74 "HS", /* 4 */
75 "","","","","","","","","","","","","","","","","","","","", /* 20x */
76 "","","","","","","","","","","","","","","","","","","","", /* 20x */
77 "","","","","","","","","","","","","","","","","","","","", /* 20x */
78 "","","","","","","","","","","","","","","","","","","","", /* 20x */
79 "","","","","","","","","","","","","","","","","","","","", /* 20x */
80 "","","","","","","","","","","","","","","","","","","","", /* 20x */
81 "","","","","","","","","","","","","","","","","","","","", /* 20x */
82 "","","","","","","","","","","","","","","","","","","","", /* 20x */
83 "","","","","","","","","","","","","","","","","","","","", /* 20x */
84 "","","","","","","","","","","","","","","","","","","","", /* 20x */
85 "","","","","","","","","","","","","","","","","","","","", /* 20x */
86 "","","","","","","","","", /* 9x */
87 "NONE", /* 254 */
88 "ANY", /* 255 */
89 };
90
91 static const char *php_ares_T_names[] = {
92 "INVALID",
93 "A",
94 "NS",
95 "MD",
96 "MF",
97 "CNAME",
98 "SOA",
99 "MB",
100 "MG",
101 "MR",
102 "NULL",
103 "WKS",
104 "PTR",
105 "HINFO",
106 "MINFO",
107 "MX",
108 "TXT",
109 "RP",
110 "AFSDB",
111 "X25",
112 "ISDN",
113 "RT",
114 "NSAP",
115 "NSAP_PTR",
116 "SIG",
117 "KEY",
118 "PX",
119 "GPOS",
120 "AAAA",
121 "LOC",
122 "NXT",
123 "EID",
124 "NIMLOC",
125 "SRV",
126 "ATMA",
127 "NAPTR",
128 "KX",
129 "CERT",
130 "A6",
131 "DNAME",
132 "SINK",
133 "OPT",
134 "APL", /* 42 */
135 "","","","","","","","","","","","","","","","","","","","", /* 20x */
136 "","","","","","","","","","","","","","","","","","","","", /* 20x */
137 "","","","","","","","","","","","","","","","","","","","", /* 20x */
138 "","","","","","","","","","","","","","","","","","","","", /* 20x */
139 "","","","","","","","","","","","","","","","","","","","", /* 20x */
140 "","","","","","","","","","","","","","","","","","","","", /* 20x */
141 "","","","","","","","","","","","","","","","","","","","", /* 20x */
142 "","","","","","","","","","","","","","","","","","","","", /* 20x */
143 "","","","","","","","","","","","","","","","","","","","", /* 20x */
144 "","","","","","","","","","","","","","","","","","","","", /* 20x */
145 "","","","","","", /* 6x */
146 "TKEY", /* 249 */
147 "TSIG",
148 "IXFR",
149 "AXFR",
150 "MAILB",
151 "MAILA",
152 "ANY", /* 255 */
153 "ZXFR", /* 256 */
154 };
155
156 #ifdef HAVE_OLD_ARES_STRERROR
157 # define PHP_ARES_ERROR(err) { \
158 char *__tmp = NULL; \
159 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err, &__tmp)); \
160 if (__tmp) ares_free_errmem(__tmp); \
161 }
162 #else
163 # define PHP_ARES_ERROR(err) \
164 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
165 #endif
166
167 #define RETURN_ARES_ERROR(err) \
168 PHP_ARES_ERROR(err); \
169 RETURN_FALSE
170 #define PHP_ARES_CB_ERROR(param) \
171 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected the " param " argument to be a valid callback")
172 #define RETURN_ARES_CB_ERROR(param) \
173 PHP_ARES_CB_ERROR(param); \
174 RETURN_FALSE
175
176 #define PHP_ARES_QUERY_BUFFER_LEN 2<<0xf
177
178 /* {{{ typedefs */
179 typedef struct _php_ares_options {
180 struct ares_options strct;
181 int flags;
182 } php_ares_options;
183
184 typedef struct _php_ares {
185 ares_channel channel;
186 php_ares_options options;
187 zend_llist queries;
188 void ***tsrm_ls;
189 unsigned in_callback:1;
190 unsigned reserved:31;
191 } php_ares;
192
193 typedef enum _php_ares_query_type {
194 PHP_ARES_CB_STD,
195 PHP_ARES_CB_HOST,
196 PHP_ARES_CB_NINFO,
197 } php_ares_query_type;
198
199 typedef enum _php_ares_query_packet_type {
200 PHP_ARES_PCKT_SEARCH,
201 PHP_ARES_PCKT_QUERY,
202 PHP_ARES_PCKT_SEND,
203 PHP_ARES_PCKT_HNAME,
204 PHP_ARES_PCKT_HADDR,
205 PHP_ARES_PCKT_NINFO,
206 } php_ares_query_packet_type;
207
208 typedef union _php_ares_query_packet_data {
209 struct {
210 char *name;
211 int name_len;
212 long type;
213 long dnsclass;
214 } search;
215 struct {
216 char *name;
217 int name_len;
218 long type;
219 long dnsclass;
220 } query;
221 struct {
222 char *buf;
223 int len;
224 } send;
225 struct {
226 char *name;
227 int name_len;
228 long family;
229 } hname;
230 struct {
231 char *addr;
232 int addr_len;
233 long family;
234 } haddr;
235 struct {
236 char *addr;
237 int addr_len;
238 long port;
239 long family;
240 long flags;
241 } ninfo;
242 } php_ares_query_packet_data;
243
244 typedef struct _php_ares_query_packet {
245 php_ares_query_packet_type type;
246 php_ares_query_packet_data data;
247 } php_ares_query_packet;
248
249 typedef union _php_ares_query_result {
250 struct {
251 zval *arr;
252 char *buf;
253 int len;
254 } std;
255 struct hostent host;
256 struct {
257 char *service;
258 char *node;
259 } ninfo;
260 } php_ares_query_result;
261
262 typedef struct _php_ares_query {
263 int id;
264 int error;
265 php_ares *ares;
266 zval *callback;
267 php_ares_query_type type;
268 php_ares_query_packet packet;
269 php_ares_query_result result;
270 } php_ares_query;
271 /* }}} */
272
273 local struct hostent *php_ares_hostent_ctor(struct hostent *host) /* {{{ */
274 {
275 if (!host) {
276 host = emalloc(sizeof(struct hostent));
277 }
278 memset(host, 0, sizeof(struct hostent));
279
280 return host;
281 }
282 /* }}} */
283
284 local void php_ares_hostent_copy(struct hostent *from, struct hostent *to) /* {{{ */
285 {
286 int i, c;
287 char **ptr;
288
289 memcpy(to, from, sizeof(struct hostent));
290 to->h_name = estrdup(from->h_name);
291 for (c = 0, ptr = from->h_aliases; *ptr; ++ptr, ++c);
292 to->h_aliases = ecalloc((c+1), sizeof(char *));
293 for (i = 0; i < c; ++i) {
294 to->h_aliases[i] = estrdup(from->h_aliases[i]);
295 }
296 for (c = 0, ptr = from->h_addr_list; *ptr; ++ptr, ++c);
297 to->h_addr_list = ecalloc((c+1), sizeof(char *));
298 for (i = 0; i < c; ++i) {
299 to->h_addr_list[i] = emalloc(from->h_length);
300 memcpy(to->h_addr_list[i], from->h_addr_list[i], from->h_length);
301 }
302 }
303 /* }}} */
304
305 local void php_ares_hostent_to_struct(struct hostent *hostent, HashTable *ht) /* {{{ */
306 {
307 zval array, *tmp;
308 char **ptr;
309
310 INIT_PZVAL(&array);
311 Z_TYPE(array) = IS_ARRAY;
312 Z_ARRVAL(array) = ht;
313
314 if (hostent) {
315 add_assoc_string(&array, "name", hostent->h_name, 1);
316
317 MAKE_STD_ZVAL(tmp);
318 array_init(tmp);
319 if (hostent->h_aliases) {
320 for (ptr = hostent->h_aliases; *ptr; ++ptr) {
321 add_next_index_string(tmp, *ptr, 1);
322 }
323 }
324 add_assoc_zval(&array, "aliases", tmp);
325 add_assoc_long(&array, "addrtype", hostent->h_addrtype);
326
327 MAKE_STD_ZVAL(tmp);
328 array_init(tmp);
329 if (hostent->h_addr_list) {
330 for (ptr = hostent->h_addr_list; *ptr; ++ptr) {
331 char name[64] = {0};
332
333 if (inet_ntop(hostent->h_addrtype, *ptr, name, sizeof(name)-1)) {
334 add_next_index_string(tmp, name, 1);
335 }
336 }
337 }
338 add_assoc_zval(&array, "addrlist", tmp);
339 }
340 }
341 /* }}} */
342
343 local void php_ares_hostent_dtor(struct hostent *host) /* {{{ */
344 {
345 char **ptr;
346
347 STR_FREE(host->h_name);
348 if (host->h_aliases) {
349 for (ptr = host->h_aliases; *ptr; ++ptr) {
350 efree(*ptr);
351 }
352 efree(host->h_aliases);
353 }
354 if (host->h_addr_list) {
355 for (ptr = host->h_addr_list; *ptr; ++ptr) {
356 efree(*ptr);
357 }
358 efree(host->h_addr_list);
359 }
360 memset(host, 0, sizeof(struct hostent));
361 }
362 /* }}} */
363
364 local void php_ares_hostent_free(struct hostent **host) /* {{{ */
365 {
366 php_ares_hostent_dtor(*host);
367 efree(*host);
368 *host = NULL;
369 }
370 /* }}} */
371
372 local php_ares_query *php_ares_query_ctor(php_ares_query *query, php_ares_query_type type, php_ares *ares, zval *callback) /* {{{ */
373 {
374 if (!query) {
375 query = emalloc(sizeof(php_ares_query));
376 }
377 memset(query, 0, sizeof(php_ares_query));
378
379 query->ares = ares;
380 query->type = type;
381 query->error = -1;
382
383 if (callback) {
384 ADDREF(callback);
385 query->callback = callback;
386 }
387
388 return query;
389 }
390 /* }}} */
391
392 local void php_ares_query_rsrc(php_ares_query *query, zval *return_value) /* {{{ */
393 {
394 TSRMLS_FETCH_FROM_CTX(query->ares->tsrm_ls);
395
396 ZEND_REGISTER_RESOURCE(return_value, query, le_ares_query);
397 query->id = Z_LVAL_P(return_value);
398 zend_list_addref(query->id);
399 zend_llist_add_element(&query->ares->queries, &query);
400 }
401 /* }}} */
402
403 local void php_ares_query_pckt(php_ares_query *query, php_ares_query_packet_type type, ...)
404 {
405 va_list argv;
406 char *buf;
407 int len;
408
409 va_start(argv, type);
410
411 switch (query->packet.type = type) {
412 case PHP_ARES_PCKT_SEARCH:
413 buf = va_arg(argv, char *);
414 len = va_arg(argv, int);
415 query->packet.data.search.name = estrndup(buf, len);
416 query->packet.data.search.name_len = len;
417 query->packet.data.search.type = va_arg(argv, long);
418 query->packet.data.search.dnsclass = va_arg(argv, long);
419 break;
420
421 case PHP_ARES_PCKT_QUERY:
422 buf = va_arg(argv, char *);
423 len = va_arg(argv, int);
424 query->packet.data.query.name = estrndup(buf, len);
425 query->packet.data.query.name_len = len;
426 query->packet.data.query.type = va_arg(argv, long);
427 query->packet.data.query.dnsclass = va_arg(argv, long);
428 break;
429
430 case PHP_ARES_PCKT_SEND:
431 buf = va_arg(argv, char *);
432 len = va_arg(argv, int);
433 query->packet.data.send.buf = estrndup(buf, len);
434 query->packet.data.send.len = len;
435 break;
436
437 case PHP_ARES_PCKT_HNAME:
438 buf = va_arg(argv, char *);
439 len = va_arg(argv, int);
440 query->packet.data.hname.name = estrndup(buf, len);
441 query->packet.data.hname.name_len = len;
442 query->packet.data.hname.family = va_arg(argv, long);
443 break;
444
445 case PHP_ARES_PCKT_HADDR:
446 buf = va_arg(argv, char *);
447 len = va_arg(argv, int);
448 query->packet.data.haddr.addr = estrndup(buf, len);
449 query->packet.data.haddr.addr_len = len;
450 query->packet.data.haddr.family = va_arg(argv, long);
451 break;
452
453 case PHP_ARES_PCKT_NINFO:
454 query->packet.data.ninfo.flags = va_arg(argv, long);
455 buf = va_arg(argv, char *);
456 len = va_arg(argv, int);
457 query->packet.data.ninfo.addr = estrndup(buf, len);
458 query->packet.data.ninfo.addr_len = len;
459 query->packet.data.ninfo.family = va_arg(argv, long);
460 query->packet.data.ninfo.port = va_arg(argv, long);
461 break;
462 }
463
464 va_end(argv);
465 }
466
467 local void php_ares_query_dtor(php_ares_query *query) /* {{{ */
468 {
469 struct php_ares_query_packet_buf {char *buf;} *packet;
470
471 packet = (struct php_ares_query_packet_buf *) &query->packet.data;
472 if (packet->buf) {
473 efree(packet->buf);
474 }
475 switch (query->type) {
476 case PHP_ARES_CB_STD:
477 if (query->result.std.arr) {
478 zval_ptr_dtor(&query->result.std.arr);
479 }
480 STR_FREE(query->result.std.buf);
481 break;
482 case PHP_ARES_CB_HOST:
483 php_ares_hostent_dtor(&query->result.host);
484 break;
485 case PHP_ARES_CB_NINFO:
486 STR_FREE(query->result.ninfo.service);
487 STR_FREE(query->result.ninfo.node);
488 break;
489 }
490 if (query->callback) {
491 zval_ptr_dtor(&query->callback);
492 }
493 memset(query, 0, sizeof(php_ares_query));
494 }
495 /* }}} */
496
497 local void php_ares_query_free(php_ares_query **query) /* {{{ */
498 {
499 php_ares_query_dtor(*query);
500 efree(*query);
501 *query = NULL;
502 }
503 /* }}} */
504
505 local zend_bool is_numeric(zval **p, long *lval) { /* {{{ */
506 zval *tmp = *p;
507 switch (Z_TYPE_PP(p)) {
508 case IS_STRING:
509 convert_to_long_ex(&tmp);
510 /* no break */
511 case IS_LONG:
512 *lval = Z_LVAL_P(tmp);
513 if (tmp != *p) {
514 zval_ptr_dtor(&tmp);
515 }
516 return !!*lval;
517 }
518 return 0;
519 } /* }}} */
520
521 local php_ares_options *php_ares_options_ctor(php_ares_options *options, HashTable *ht) /* {{{ */
522 {
523 int i;
524 long lval;
525 zval **opt, **entry;
526
527 if (!options) {
528 options = emalloc(sizeof(php_ares_options));
529 }
530 memset(options, 0, sizeof(php_ares_options));
531
532 if (ht && zend_hash_num_elements(ht)) {
533 if ((SUCCESS == zend_hash_find(ht, "flags", sizeof("flags"), (void *) &opt)) && is_numeric(opt, &lval)) {
534 options->flags |= ARES_OPT_FLAGS;
535 options->strct.flags = lval;
536 }
537 #ifdef ARES_OPT_TIMEOUTMS
538 if ((SUCCESS == zend_hash_find(ht, "timeoutms", sizeof("timeoutms"), (void *) &opt)) && is_numeric(opt, &lval)) {
539 options->flags |= ARES_OPT_TIMEOUTMS;
540 options->strct.timeout = lval;
541 } else
542 #endif
543 if ((SUCCESS == zend_hash_find(ht, "timeout", sizeof("timeout"), (void *) &opt)) && is_numeric(opt, &lval)) {
544 options->flags |= ARES_OPT_TIMEOUT;
545 options->strct.timeout = lval;
546 }
547 if ((SUCCESS == zend_hash_find(ht, "tries", sizeof("tries"), (void *) &opt)) && is_numeric(opt, &lval)) {
548 options->flags |= ARES_OPT_TRIES;
549 options->strct.tries = lval;
550 }
551 if ((SUCCESS == zend_hash_find(ht, "ndots", sizeof("ndots"), (void *) &opt)) && is_numeric(opt, &lval)) {
552 options->flags |= ARES_OPT_NDOTS;
553 options->strct.ndots = lval;
554 }
555 if ((SUCCESS == zend_hash_find(ht, "udp_port", sizeof("udp_port"), (void *) &opt)) && is_numeric(opt, &lval)) {
556 options->flags |= ARES_OPT_UDP_PORT;
557 #ifdef PHP_ARES_CARES
558 options->strct.udp_port = (unsigned short) lval;
559 #else
560 options->strct.udp_port = htons((unsigned short) lval);
561 #endif
562 }
563 if ((SUCCESS == zend_hash_find(ht, "tcp_port", sizeof("tcp_port"), (void *) &opt)) && is_numeric(opt, &lval)) {
564 options->flags |= ARES_OPT_TCP_PORT;
565 #ifdef PHP_ARES_CARES
566 options->strct.tcp_port = (unsigned short) lval;
567 #else
568 options->strct.tcp_port = htons((unsigned short) lval);
569 #endif
570 }
571 if ((SUCCESS == zend_hash_find(ht, "servers", sizeof("servers"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_ARRAY) && (i = zend_hash_num_elements(Z_ARRVAL_PP(opt)))) {
572 options->strct.servers = ecalloc(i, sizeof(struct in_addr));
573 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
574 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
575 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
576 if (Z_TYPE_PP(entry) == IS_STRING) {
577 inet_aton(Z_STRVAL_PP(entry), &options->strct.servers[options->strct.nservers++]);
578 }
579 }
580 if (options->strct.nservers) {
581 options->flags |= ARES_OPT_SERVERS;
582 }
583 }
584 if ((SUCCESS == zend_hash_find(ht, "domains", sizeof("domains"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_ARRAY) && (i = zend_hash_num_elements(Z_ARRVAL_PP(opt)))) {
585 options->strct.domains = ecalloc(i, sizeof(char *));
586 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
587 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
588 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
589 if (Z_TYPE_PP(entry) == IS_STRING) {
590 options->strct.domains[options->strct.ndomains++] = estrdup(Z_STRVAL_PP(entry));
591 }
592 }
593 if (options->strct.ndomains) {
594 options->flags |= ARES_OPT_DOMAINS;
595 }
596 }
597 if ((SUCCESS == zend_hash_find(ht, "lookups", sizeof("lookups"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_STRING)) {
598 options->flags |= ARES_OPT_LOOKUPS;
599 options->strct.lookups = estrdup(Z_STRVAL_PP(opt));
600 }
601 #ifdef ARES_OPT_ROTATE
602 if ((SUCCESS == zend_hash_find(ht, "rotate", sizeof("rotate"), (void *) &opt)) && i_zend_is_true(*opt)) {
603 options->flags |= ARES_OPT_ROTATE;
604 }
605 #endif
606 #ifdef ARES_OPT_EDNSPSZ
607 if ((SUCCESS == zend_hash_find(ht, "ednspsz", sizeof("ednspsz"), (void *) &opt)) && is_numeric(opt, &lval)) {
608 options->flags |= ARES_OPT_EDNSPSZ;
609 options->strct.ednspsz = lval;
610 }
611 #endif
612 }
613
614 return options;
615 }
616 /* }}} */
617
618 local void php_ares_options_dtor(php_ares_options *options) /* {{{ */
619 {
620 int i;
621
622 if (options->strct.servers) {
623 efree(options->strct.servers);
624 }
625
626 if (options->strct.domains) {
627 for (i = 0; i < options->strct.ndomains; ++i) {
628 efree(options->strct.domains[i]);
629 }
630 efree(options->strct.domains);
631 }
632
633 STR_FREE(options->strct.lookups);
634
635 memset(options, 0, sizeof(php_ares_options));
636 }
637 /* }}} */
638
639 local void php_ares_options_free(php_ares_options **options) /* {{{ */
640 {
641 php_ares_options_dtor(*options);
642 efree(*options);
643 *options = NULL;
644 }
645 /* }}} */
646
647 local PHP_ARES_EXPAND_LEN_TYPE php_ares_skip(const unsigned char *pointer, const unsigned char *abuf, int alen TSRMLS_DC)
648 {
649 char *name;
650 int rc;
651 PHP_ARES_EXPAND_LEN_TYPE byte_count;
652
653 /* NOTE: byte_count is not neccessarily the length of the string,
654 i.e. if there were back references */
655 if (ARES_SUCCESS == (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
656 /*fprintf(stderr, "-- skipping %s\n", name);*/
657 ares_free_string(name);
658 return byte_count;
659 }
660 PHP_ARES_ERROR(rc);
661 return -1;
662 }
663
664 local int php_ares_parse(const unsigned char *abuf, int alen, zval *result TSRMLS_DC) /* {{{ */
665 {
666 HEADER *header;
667 PHP_ARES_EXPAND_LEN_TYPE byte_count;
668 const unsigned char *pointer;
669 char *name;
670 int rc, query_count, answer_count;
671
672 convert_to_array(result);
673
674 if (!alen || !abuf || !*abuf) {
675 return SUCCESS;
676 }
677
678 header = (HEADER *) abuf;
679 pointer = abuf + HFIXEDSZ;
680
681 for (query_count = ntohs(header->qdcount); query_count--; pointer += byte_count + QFIXEDSZ) {
682 if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
683 return FAILURE;
684 }
685 }
686
687 for (answer_count = ntohs(header->ancount); answer_count-- && pointer < (abuf + alen); ) {
688 uint16_t stmp, type, class;
689 uint32_t ltmp, ttl;
690 zval *entry = NULL;
691
692 if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
693 return FAILURE;
694 }
695
696 pointer += byte_count;
697
698 MAKE_STD_ZVAL(entry);
699 array_init(entry);
700
701 GETSHORT(type, pointer);
702 add_assoc_string(entry, "type", estrdup(php_ares_T_names[type]), 0);
703 GETSHORT(class, pointer);
704 add_assoc_string(entry, "class", estrdup(php_ares_C_names[class]), 0);
705 GETLONG(ttl, pointer);
706 add_assoc_long(entry, "ttl", ttl);
707 GETSHORT(byte_count, pointer);
708 #if 0
709 fprintf(stderr, ">> processing %s answer of length %d\n", php_ares_T_names[type], byte_count);
710 #endif
711 switch (type) {
712 case T_A:
713 spprintf(&name, 0, "%d.%d.%d.%d", pointer[0], pointer[1], pointer[2], pointer[3]);
714 add_assoc_string(entry, "addr", name, 0);
715 pointer += byte_count;
716 break;
717
718 case T_NS:
719 case T_PTR:
720 case T_CNAME:
721 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
722 PHP_ARES_ERROR(rc);
723 return FAILURE;
724 }
725 pointer += byte_count;
726 add_assoc_string(entry, "name", name, 1);
727 ares_free_string(name);
728 break;
729
730 case T_MX:
731 GETSHORT(stmp, pointer);
732 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
733 PHP_ARES_ERROR(rc);
734 return FAILURE;
735 }
736 pointer += byte_count;
737 add_assoc_long(entry, "weight", stmp);
738 add_assoc_string(entry, "name", name, 1);
739 ares_free_string(name);
740 break;
741
742 case T_SRV:
743 GETSHORT(stmp, pointer);
744 add_assoc_long(entry, "priority", stmp);
745 GETSHORT(stmp, pointer);
746 add_assoc_long(entry, "weight", stmp);
747 GETSHORT(stmp, pointer);
748 add_assoc_long(entry, "port", stmp);
749
750 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
751 PHP_ARES_ERROR(rc);
752 zval_ptr_dtor(&entry);
753 return FAILURE;
754 }
755 pointer += byte_count;
756 add_assoc_string(entry, "name", name, 1);
757 ares_free_string(name);
758 break;
759
760 case T_SOA:
761 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
762 PHP_ARES_ERROR(rc);
763 zval_ptr_dtor(&entry);
764 return FAILURE;
765 }
766 pointer += byte_count;
767 add_assoc_string(entry, "name", name, 1);
768 ares_free_string(name);
769
770 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
771 PHP_ARES_ERROR(rc);
772 zval_ptr_dtor(&entry);
773 return FAILURE;
774 }
775 pointer += byte_count;
776 add_assoc_string(entry, "mail", name, 1);
777 ares_free_string(name);
778
779 GETLONG(ltmp, pointer);
780 add_assoc_long(entry, "serial", ltmp);
781 GETLONG(ltmp, pointer);
782 add_assoc_long(entry, "refresh", ltmp);
783 GETLONG(ltmp, pointer);
784 add_assoc_long(entry, "retry", ltmp);
785 GETLONG(ltmp, pointer);
786 add_assoc_long(entry, "expire", ltmp);
787 GETLONG(ltmp, pointer);
788 add_assoc_long(entry, "minimum-ttl", ltmp);
789 break;
790
791 case T_TXT:
792 for (ltmp = 0; ltmp < byte_count; ltmp += pointer[ltmp] + 1) {
793 add_next_index_stringl(entry, (const char *) &pointer[ltmp + 1], pointer[ltmp], 1);
794 }
795 pointer += byte_count;
796 break;
797
798 default:
799 zval_ptr_dtor(&entry);
800 entry = NULL;
801 pointer += byte_count;
802 break;
803 }
804
805 if (entry) {
806 add_next_index_zval(result, entry);
807 }
808 }
809
810 return SUCCESS;
811 }
812 /* }}} */
813
814 /* {{{ callbacks */
815 static void php_ares_callback_func_old(void *aq, int status, unsigned char *abuf, int alen)
816 {
817 php_ares_query *q = (php_ares_query *) aq;
818 zval *params[4], *retval, *parsed = NULL;
819 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
820
821 q->error = status;
822 if (abuf) {
823 q->result.std.buf = estrndup((char *) abuf, alen);
824 q->result.std.len = alen;
825
826 MAKE_STD_ZVAL(parsed);
827 ZVAL_NULL(parsed);
828 if (SUCCESS == php_ares_parse(abuf, alen, parsed TSRMLS_CC)) {
829 q->result.std.arr = parsed;
830 } else {
831 zval_ptr_dtor(&parsed);
832 parsed = NULL;
833 }
834 }
835
836 if (q->callback) {
837 MAKE_STD_ZVAL(retval);
838 MAKE_STD_ZVAL(params[0]);
839 MAKE_STD_ZVAL(params[1]);
840 MAKE_STD_ZVAL(params[2]);
841 ZVAL_NULL(retval);
842 zend_list_addref(q->id);
843 Z_LVAL_P(params[0]) = q->id;
844 Z_TYPE_P(params[0]) = IS_RESOURCE;
845 ZVAL_LONG(params[1], status);
846 ZVAL_STRINGL(params[2], (char *) abuf, alen, 1);
847
848 if (parsed) {
849 ADDREF(parsed);
850 params[3] = parsed;
851 }
852
853 q->ares->in_callback = 1;
854 call_user_function(EG(function_table), NULL, q->callback, retval, parsed ? 4 : 3, params TSRMLS_CC);
855 q->ares->in_callback = 0;
856
857 zval_ptr_dtor(&retval);
858 zval_ptr_dtor(&params[0]);
859 zval_ptr_dtor(&params[1]);
860 zval_ptr_dtor(&params[2]);
861
862 if (parsed) {
863 zval_ptr_dtor(&params[3]);
864 }
865 }
866 }
867
868 static void php_ares_host_callback_func_old(void *aq, int status, struct hostent *hostent)
869 {
870 php_ares_query *q = (php_ares_query *) aq;
871 zval *params[3], *retval;
872 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
873
874 q->error = status;
875 if (hostent) {
876 php_ares_hostent_copy(hostent, &q->result.host);
877 }
878
879 if (q->callback) {
880 MAKE_STD_ZVAL(retval);
881 MAKE_STD_ZVAL(params[0]);
882 MAKE_STD_ZVAL(params[1]);
883 MAKE_STD_ZVAL(params[2]);
884 ZVAL_NULL(retval);
885 zend_list_addref(q->id);
886 Z_LVAL_P(params[0]) = q->id;
887 Z_TYPE_P(params[0]) = IS_RESOURCE;
888 ZVAL_LONG(params[1], status);
889 object_init(params[2]);
890 php_ares_hostent_to_struct(hostent, HASH_OF(params[2]));
891
892 q->ares->in_callback = 1;
893 call_user_function(EG(function_table), NULL, q->callback, retval, 3, params TSRMLS_CC);
894 q->ares->in_callback = 0;
895
896 zval_ptr_dtor(&retval);
897 zval_ptr_dtor(&params[0]);
898 zval_ptr_dtor(&params[1]);
899 zval_ptr_dtor(&params[2]);
900 }
901 }
902
903 #ifdef HAVE_ARES_GETNAMEINFO
904 static void php_ares_nameinfo_callback_func_old(void *aq, int status, char *node, char *service)
905 {
906 php_ares_query *q = (php_ares_query *) aq;
907 zval *params[4], *retval;
908 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
909
910 q->error = status;
911 if (node) {
912 q->result.ninfo.node = estrdup(node);
913 }
914 if (service) {
915 q->result.ninfo.service = estrdup(service);
916 }
917
918 if (q->callback) {
919 MAKE_STD_ZVAL(retval);
920 MAKE_STD_ZVAL(params[0]);
921 MAKE_STD_ZVAL(params[1]);
922 MAKE_STD_ZVAL(params[2]);
923 MAKE_STD_ZVAL(params[3]);
924 ZVAL_NULL(retval);
925 zend_list_addref(q->id);
926 Z_LVAL_P(params[0]) = q->id;
927 Z_TYPE_P(params[0]) = IS_RESOURCE;
928 ZVAL_LONG(params[1], status);
929 if (node) {
930 ZVAL_STRING(params[2], node, 1);
931 } else {
932 ZVAL_NULL(params[2]);
933 }
934 if (service) {
935 ZVAL_STRING(params[3], service, 1);
936 } else {
937 ZVAL_NULL(params[3]);
938 }
939
940 q->ares->in_callback = 1;
941 call_user_function(EG(function_table), NULL, q->callback, retval, 4, params TSRMLS_CC);
942 q->ares->in_callback = 0;
943
944 zval_ptr_dtor(&retval);
945 zval_ptr_dtor(&params[0]);
946 zval_ptr_dtor(&params[1]);
947 zval_ptr_dtor(&params[2]);
948 zval_ptr_dtor(&params[3]);
949 }
950 }
951 #endif
952
953 #if PHP_ARES_NEW_CALLBACK_API
954 # define php_ares_callback_func php_ares_callback_func_new
955 static void php_ares_callback_func_new(void *aq, int status, int timeouts, unsigned char *abuf, int alen)
956 {
957 php_ares_callback_func_old(aq, status, abuf, alen);
958 }
959
960 # define php_ares_host_callback_func php_ares_host_callback_func_new
961 static void php_ares_host_callback_func_new(void *aq, int status, int timeouts, struct hostent *hostent)
962 {
963 php_ares_host_callback_func_old(aq, status, hostent);
964 }
965
966 # ifdef HAVE_ARES_GETNAMEINFO
967 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
968 static void php_ares_nameinfo_callback_func_new(void *aq, int status, int timeouts, char *node, char *service)
969 {
970 php_ares_nameinfo_callback_func_old(aq, status, node, service);
971 }
972 # endif
973
974 #else
975 # define php_ares_callback_func php_ares_callback_func_old
976 # define php_ares_host_callback_func php_ares_host_callback_func_old
977 # ifdef HAVE_ARES_GETNAMEINFO
978 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
979 # endif
980 #endif
981 /* }}} */
982
983 local struct timeval *php_ares_timeout(php_ares *ares, long max_timeout, struct timeval *tv_buf) /* {{{ */
984 {
985 struct timeval maxtv;
986
987 if (max_timeout > -1) {
988 maxtv.tv_sec = max_timeout / 1000;
989 maxtv.tv_usec = max_timeout % (max_timeout * 1000);
990 }
991
992 return ares_timeout(ares->channel, max_timeout > -1 ? &maxtv : NULL, tv_buf);
993 }
994 /* }}} */
995
996 local int php_ares_process(php_ares *ares, long max_timeout) /* {{{ */
997 {
998 int nfds;
999 fd_set R, W;
1000 struct timeval tv;
1001
1002 FD_ZERO(&R);
1003 FD_ZERO(&W);
1004
1005 if ((nfds = ares_fds(ares->channel, &R, &W))) {
1006 if (0 < select(nfds, &R, &W, NULL, php_ares_timeout(ares, max_timeout, &tv))) {
1007 ares_process(ares->channel, &R, &W);
1008 }
1009 }
1010
1011 return nfds;
1012 }
1013 /* }}} */
1014
1015 local int php_ares_publish_fds(fd_set *R, fd_set *W, zval *r, zval *w, HashTable *resource_map) /* {{{ */
1016 {
1017 int i, nfds = 0;
1018 zval **fd;
1019
1020 for (i = 0; i < FD_SETSIZE; ++i) {
1021 if (FD_ISSET(i, R)) {
1022 if (resource_map && (SUCCESS == zend_hash_index_find(resource_map, i, (void *) &fd))) {
1023 zval_add_ref(fd);
1024 add_next_index_zval(r, *fd);
1025 } else {
1026 add_next_index_long(r, i);
1027 }
1028 if (i > nfds) {
1029 nfds = i;
1030 }
1031 }
1032 }
1033
1034 for (i = 0; i < FD_SETSIZE; ++i) {
1035 if (FD_ISSET(i, W)) {
1036 if (resource_map && (SUCCESS == zend_hash_index_find(resource_map, i, (void *) &fd))) {
1037 zval_add_ref(fd);
1038 add_next_index_zval(r, *fd);
1039 } else {
1040 add_next_index_long(w, i);
1041 }
1042 if (i > nfds) {
1043 nfds = i;
1044 }
1045 }
1046 }
1047
1048 return nfds ? nfds + 1 : 0;
1049 }
1050 /* }}} */
1051
1052 local int php_ares_extract_fds(zval *r, zval *w, fd_set *R, fd_set *W, HashTable *resource_map TSRMLS_DC) /* {{{ */
1053 {
1054 zval **fd;
1055 int nfds = 0;
1056 zval zmap;
1057
1058 INIT_ZVAL(zmap);
1059 Z_ARRVAL(zmap) = resource_map;
1060 Z_TYPE(zmap) = IS_ARRAY;
1061 if (r && zend_hash_num_elements(Z_ARRVAL_P(r))) {
1062 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r));
1063 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(r), (void *) &fd);
1064 zend_hash_move_forward(Z_ARRVAL_P(r))) {
1065 if (Z_TYPE_PP(fd) == IS_RESOURCE) {
1066 php_stream *s = NULL;
1067 int id = 0;
1068
1069 ZEND_FETCH_RESOURCE_NO_RETURN(s, php_stream *, fd, -1, NULL, php_file_le_stream());
1070 if (s && (SUCCESS == php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT, (void *) &id, 1))) {
1071 zval_add_ref(fd);
1072 add_index_zval(&zmap, id, *fd);
1073 FD_SET(id, R);
1074 if (id > nfds) {
1075 nfds = id;
1076 }
1077 }
1078 } else if (Z_TYPE_PP(fd) == IS_LONG) {
1079 FD_SET(Z_LVAL_PP(fd), R);
1080 if (Z_LVAL_PP(fd) > nfds) {
1081 nfds = Z_LVAL_PP(fd);
1082 }
1083 }
1084 }
1085 }
1086
1087 if (w && zend_hash_num_elements(Z_ARRVAL_P(w))) {
1088 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w));
1089 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(w), (void *) &fd);
1090 zend_hash_move_forward(Z_ARRVAL_P(w))) {
1091 if (Z_TYPE_PP(fd) == IS_RESOURCE) {
1092 php_stream *s = NULL;
1093 int id = 0;
1094
1095 ZEND_FETCH_RESOURCE_NO_RETURN(s, php_stream *, fd, -1, NULL, php_file_le_stream());
1096 if (s && (SUCCESS == php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT, (void *) &id, 1))) {
1097 zval_add_ref(fd);
1098 add_index_zval(&zmap, id, *fd);
1099 FD_SET(id, W);
1100 if (id > nfds) {
1101 nfds = id;
1102 }
1103 }
1104 } else if (Z_TYPE_PP(fd) == IS_LONG) {
1105 FD_SET(Z_LVAL_PP(fd), W);
1106 if (Z_LVAL_PP(fd) > nfds) {
1107 nfds = Z_LVAL_PP(fd);
1108 }
1109 }
1110 }
1111 }
1112
1113 return nfds ? nfds + 1 : 0;
1114 }
1115 /* }}} */
1116
1117 static void php_ares_query_llist_dtor(void *entry)
1118 {
1119 php_ares_query *q = *(php_ares_query **) entry;
1120 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
1121 zend_list_delete(q->id);
1122 }
1123
1124 #ifdef HAVE_ARES_VERSION
1125 /* {{{ proto string ares_version()
1126 Get libares version */
1127 static PHP_FUNCTION(ares_version)
1128 {
1129 if (ZEND_NUM_ARGS()) {
1130 WRONG_PARAM_COUNT;
1131 }
1132
1133 RETURN_STRING(estrdup(ares_version(NULL)), 0);
1134 }
1135 /* }}} */
1136 #endif
1137
1138 /* {{{ proto resource ares_init([array options])
1139 Create an ares resource */
1140 static PHP_FUNCTION(ares_init)
1141 {
1142 zval *opt_array = NULL;
1143 php_ares *ares = NULL;
1144 int err;
1145
1146 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &opt_array)) {
1147 RETURN_FALSE;
1148 }
1149
1150 ares = ecalloc(1, sizeof(php_ares));
1151 TSRMLS_SET_CTX(ares->tsrm_ls);
1152 zend_llist_init(&ares->queries, sizeof(php_ares_query *), (llist_dtor_func_t) php_ares_query_llist_dtor, 0);
1153 php_ares_options_ctor(&ares->options, opt_array ? Z_ARRVAL_P(opt_array) : NULL);
1154
1155 if (ARES_SUCCESS != (err = ares_init_options(&ares->channel, &ares->options.strct, ares->options.flags))) {
1156 php_ares_options_dtor(&ares->options);
1157 zend_llist_destroy(&ares->queries);
1158 efree(ares);
1159 RETURN_ARES_ERROR(err);
1160 }
1161
1162 ZEND_REGISTER_RESOURCE(return_value, ares, le_ares);
1163 }
1164 /* }}} */
1165
1166 #ifdef HAVE_ARES_SET_LOCAL_DEV
1167 /* {{{ proto void ares_set_local_dev(resource ares, string dev)
1168 Set the local interface name to bind to. */
1169 static PHP_FUNCTION(ares_set_local_dev)
1170 {
1171 zval *rsrc;
1172 char *dev_str = NULL;
1173 int dev_len = 0;
1174 php_ares *ares;
1175
1176 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!", &rsrc, &dev_str, &dev_len)) {
1177 RETURN_FALSE;
1178 }
1179 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1180
1181 ares_set_local_dev(ares->channel, dev_str);
1182 }
1183 #endif
1184
1185 #ifdef HAVE_ARES_SET_LOCAL_IP4
1186 /* {{{ proto void ares_set_local_ip4(resource ares, int addr)
1187 Set the local IPv4 address to bind to. */
1188 static PHP_FUNCTION(ares_set_local_ip4)
1189 {
1190 zval *rsrc;
1191 long ip4_num;
1192 php_ares *ares;
1193
1194 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &rsrc, &ip4_num)) {
1195 RETURN_FALSE;
1196 }
1197 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1198
1199 ares_set_local_ip4(ares->channel, (unsigned int) ip4_num);
1200 }
1201 #endif
1202
1203 #ifdef HAVE_ARES_SET_LOCAL_IP6
1204 /* {{{ proto void ares_set_local_ip6(resource ares, string addr128bit)
1205 Set the local IPv6 address to bind to. */
1206 static PHP_FUNCTION(ares_set_local_ip6)
1207 {
1208 zval *rsrc;
1209 char *ip6_str;
1210 int ip6_len;
1211 php_ares *ares;
1212
1213 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &ip6_str, &ip6_len)) {
1214 RETURN_FALSE;
1215 }
1216 if (16 != ip6_len) {
1217 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary IPv6 address string must be exactly 16 bytes long");
1218 }
1219 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1220
1221 ares_set_local_ip6(ares->channel, (unsigned char *) ip6_str);
1222 }
1223 #endif
1224
1225 /* {{{ proto void ares_destroy(resource ares)
1226 Destroy the ares handle */
1227 static PHP_FUNCTION(ares_destroy)
1228 {
1229 zval *rsrc;
1230 php_ares *ares;
1231
1232 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1233 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1234 if (ares->in_callback) {
1235 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy ares handle while in callback");
1236 } else {
1237 zend_list_delete(Z_LVAL_P(rsrc));
1238 }
1239 }
1240 }
1241 /* }}} */
1242
1243 /* {{{ proto string ares_strerror(int status)
1244 Get description of status code */
1245 static PHP_FUNCTION(ares_strerror)
1246 {
1247 long err;
1248 #ifdef HAVE_OLD_ARES_STRERROR
1249 char *__tmp = NULL;
1250 const char *__err;
1251 #endif
1252
1253 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &err)) {
1254 RETURN_FALSE;
1255 }
1256
1257 #ifdef HAVE_OLD_ARES_STRERROR
1258 __err = ares_strerror(err, &__tmp);
1259 RETVAL_STRING(estrdup(__err), 0);
1260 if (__tmp) {
1261 ares_free_errmem(__tmp);
1262 }
1263 #else
1264 RETURN_STRING(estrdup(ares_strerror(err)), 0);
1265 #endif
1266 }
1267 /* }}} */
1268
1269 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
1270 Compose a custom query */
1271 static PHP_FUNCTION(ares_mkquery)
1272 {
1273 char *name_str, *query_str;
1274 int name_len, query_len, err;
1275 long dnsclass, type, id, rd;
1276
1277 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &name_str, &name_len, &dnsclass, &type, &id, &rd)) {
1278 RETURN_FALSE;
1279 }
1280
1281 if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, (unsigned char **) &query_str, &query_len))) {
1282 RETURN_ARES_ERROR(err);
1283 }
1284 RETVAL_STRINGL(query_str, query_len, 1);
1285 ares_free_string(query_str);
1286 }
1287 /* }}} */
1288
1289 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1290 Issue a domain search for name */
1291 static PHP_FUNCTION(ares_search)
1292 {
1293 zval *rsrc, *cb = NULL;
1294 php_ares *ares;
1295 php_ares_query *query;
1296 char *name;
1297 int name_len;
1298 long dnsclass = C_IN, type = T_A;
1299
1300 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
1301 RETURN_FALSE;
1302 }
1303 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1304
1305 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1306 RETURN_ARES_CB_ERROR("second");
1307 }
1308
1309 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1310 php_ares_query_rsrc(query, return_value);
1311 php_ares_query_pckt(query, PHP_ARES_PCKT_SEARCH, name, name_len, type, dnsclass);
1312 ares_search(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
1313 }
1314 /* }}} */
1315
1316 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1317 Issue a single DNS query */
1318 static PHP_FUNCTION(ares_query)
1319 {
1320 zval *rsrc, *cb = NULL;
1321 php_ares *ares;
1322 php_ares_query *query;
1323 char *name;
1324 int name_len;
1325 long dnsclass = C_IN, type = T_A;
1326
1327 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
1328 RETURN_FALSE;
1329 }
1330 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1331
1332 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1333 RETURN_ARES_CB_ERROR("second");
1334 }
1335
1336 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1337 php_ares_query_rsrc(query, return_value);
1338 php_ares_query_pckt(query, PHP_ARES_PCKT_QUERY, name, name_len, type, dnsclass);
1339 ares_query(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
1340 }
1341 /* }}} */
1342
1343 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
1344 Send custom query */
1345 static PHP_FUNCTION(ares_send)
1346 {
1347 zval *rsrc, *cb = NULL;
1348 php_ares *ares;
1349 php_ares_query *query;
1350 char *buf;
1351 int len;
1352
1353 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s", &rsrc, &cb, &buf, &len)) {
1354 RETURN_FALSE;
1355 }
1356 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1357
1358 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1359 RETURN_ARES_CB_ERROR("second");
1360 }
1361
1362 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1363 php_ares_query_rsrc(query, return_value);
1364 php_ares_query_pckt(query, PHP_ARES_PCKT_SEND, buf, len);
1365 ares_send(ares->channel, (const unsigned char *) buf, len, php_ares_callback_func, query);
1366 }
1367 /* }}} */
1368
1369 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
1370 Get host by name */
1371 static PHP_FUNCTION(ares_gethostbyname)
1372 {
1373 zval *rsrc, *cb = NULL;
1374 php_ares *ares;
1375 php_ares_query *query;
1376 char *name;
1377 int name_len;
1378 long family = AF_INET;
1379
1380 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &name, &name_len, &family)) {
1381 RETURN_FALSE;
1382 }
1383 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1384
1385 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1386 RETURN_ARES_CB_ERROR("second");
1387 }
1388
1389 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
1390 php_ares_query_rsrc(query, return_value);
1391 php_ares_query_pckt(query, PHP_ARES_PCKT_HNAME, name, name_len, family);
1392 ares_gethostbyname(ares->channel, name, family, php_ares_host_callback_func, query);
1393 }
1394 /* }}} */
1395
1396 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
1397 Get host by address */
1398 static PHP_FUNCTION(ares_gethostbyaddr)
1399 {
1400 zval *rsrc, *cb = NULL;
1401 php_ares *ares;
1402 php_ares_query *query;
1403 char *addr;
1404 int addr_len;
1405 long family = AF_INET;
1406 void *sa;
1407 int sa_len;
1408
1409 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &addr, &addr_len, &family)) {
1410 RETURN_FALSE;
1411 }
1412 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1413
1414 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1415 PHP_ARES_CB_ERROR("second");
1416 RETURN_FALSE;
1417 }
1418
1419 switch (family) {
1420 case AF_INET:
1421 sa = emalloc(sa_len = sizeof(struct in_addr));
1422 break;
1423 case AF_INET6:
1424 sa = emalloc(sa_len = sizeof(struct in6_addr));
1425 break;
1426 default:
1427 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1428 RETURN_FALSE;
1429 break;
1430 }
1431
1432 if (1 > inet_pton(family, addr, sa)) {
1433 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1434 RETVAL_FALSE;
1435 } else {
1436 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
1437 php_ares_query_rsrc(query, return_value);
1438 php_ares_query_pckt(query, PHP_ARES_PCKT_HADDR, addr, addr_len, family);
1439 ares_gethostbyaddr(ares->channel, sa, sa_len, family, php_ares_host_callback_func, query);
1440 }
1441 efree(sa);
1442 }
1443 /* }}} */
1444
1445 #ifdef HAVE_ARES_GETNAMEINFO
1446 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1447 Get name info */
1448 static PHP_FUNCTION(ares_getnameinfo)
1449 {
1450 zval *rsrc, *cb = NULL;
1451 php_ares *ares;
1452 php_ares_query *query;
1453 char *addr;
1454 int addr_len;
1455 long flags, port = 0, family = AF_INET;
1456 struct sockaddr *sa;
1457 struct sockaddr_in *in;
1458 struct sockaddr_in6 *in6;
1459 int sa_len;
1460
1461 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!ls|ll", &rsrc, &cb, &flags, &addr, &addr_len, &family, &port)) {
1462 RETURN_FALSE;
1463 }
1464 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1465
1466 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1467 PHP_ARES_CB_ERROR("second");
1468 RETURN_FALSE;
1469 }
1470
1471 RETVAL_TRUE;
1472 switch (family) {
1473 case AF_INET:
1474 in = ecalloc(1, sa_len = sizeof(struct sockaddr_in));
1475 in->sin_family = AF_INET;
1476 in->sin_port = htons((unsigned short) port);
1477 if (1 > inet_pton(in->sin_family, addr, &in->sin_addr)) {
1478 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1479 RETVAL_FALSE;
1480 }
1481 sa = (struct sockaddr *) in;
1482 break;
1483 case AF_INET6:
1484 in6 = ecalloc(1, sa_len = sizeof(struct sockaddr_in6));
1485 in6->sin6_family = AF_INET6;
1486 in6->sin6_port = htons((unsigned short) port);
1487 if (1 > inet_pton(in6->sin6_family, addr, &in6->sin6_addr)) {
1488 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1489 RETVAL_FALSE;
1490 }
1491 sa = (struct sockaddr *) in6;
1492 break;
1493 default:
1494 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither AF_INET nor AF_INET6");
1495 RETURN_FALSE;
1496 break;
1497 }
1498
1499 if (Z_BVAL_P(return_value)) {
1500 query = php_ares_query_ctor(NULL, PHP_ARES_CB_NINFO, ares, cb);
1501 php_ares_query_rsrc(query, return_value);
1502 php_ares_query_pckt(query, PHP_ARES_PCKT_NINFO, flags, addr, addr_len, family, port);
1503 ares_getnameinfo(ares->channel, sa, sa_len, flags, php_ares_nameinfo_callback_func, query);
1504 }
1505 efree(sa);
1506 }
1507 /* }}} */
1508 #endif
1509
1510 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1511 Check a query for its result */
1512 static PHP_FUNCTION(ares_result)
1513 {
1514 zval *rsrc, *zerrno = NULL, *zerror = NULL;
1515 php_ares_query *query;
1516
1517 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|zz", &rsrc, &zerrno, &zerror)) {
1518 RETURN_FALSE;
1519 }
1520 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1521
1522 if (zerrno) {
1523 zval_dtor(zerrno);
1524 ZVAL_LONG(zerrno, query->error);
1525 }
1526 if (zerror) {
1527 zval_dtor(zerror);
1528 ZVAL_NULL(zerror);
1529 }
1530
1531 switch (query->error) {
1532 case 0:
1533 switch (query->type) {
1534 case PHP_ARES_CB_STD:
1535 if (query->result.std.arr) {
1536 RETVAL_ZVAL(query->result.std.arr, 1, 0);
1537 } else {
1538 RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
1539 }
1540 break;
1541 case PHP_ARES_CB_HOST:
1542 object_init(return_value);
1543 php_ares_hostent_to_struct(&query->result.host, HASH_OF(return_value));
1544 break;
1545 case PHP_ARES_CB_NINFO:
1546 object_init(return_value);
1547 add_property_string(return_value, "node", query->result.ninfo.node ? query->result.ninfo.node : "", 1);
1548 add_property_string(return_value, "service", query->result.ninfo.service ? query->result.ninfo.service : "", 1);
1549 break;
1550 }
1551 break;
1552 case -1:
1553 RETVAL_FALSE;
1554 break;
1555 default:
1556 if (zerror) {
1557 #ifdef HAVE_OLD_ARES_STRERROR
1558 char *__tmp = NULL;
1559 const char *__err = ares_strerror(query->error, &__tmp);
1560 ZVAL_STRING(zerror, estrdup(__err), 0);
1561 if (__tmp) ares_free_errmem(__tmp);
1562 #else
1563 ZVAL_STRING(zerror, estrdup(ares_strerror(query->error)), 0);
1564 #endif
1565 }
1566 RETVAL_FALSE;
1567 break;
1568 }
1569 }
1570 /* }}} */
1571
1572 /* {{{ proto object ares_packet(resource query)
1573 Check a query for its question packet */
1574 static PHP_FUNCTION(ares_packet)
1575 {
1576 zval *rsrc, *prop;
1577 php_ares_query *query;
1578
1579 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1580 RETURN_FALSE;
1581 }
1582 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1583
1584 object_init(return_value);
1585 add_property_long(return_value, "type", query->packet.type);
1586 add_property_null(return_value, "search");
1587 add_property_null(return_value, "query");
1588 add_property_null(return_value, "send");
1589 add_property_null(return_value, "gethostbyname");
1590 add_property_null(return_value, "gethostbyaddr");
1591 add_property_null(return_value, "getnameinfo");
1592 MAKE_STD_ZVAL(prop);
1593
1594 switch (query->packet.type) {
1595 case PHP_ARES_PCKT_SEARCH:
1596 object_init(prop);
1597 add_property_stringl(prop, "name", query->packet.data.search.name, query->packet.data.search.name_len, 1);
1598 add_property_long(prop, "type", query->packet.data.search.type);
1599 add_property_long(prop, "dnsclass", query->packet.data.search.dnsclass);
1600 add_property_zval(return_value, "search", prop);
1601 break;
1602
1603 case PHP_ARES_PCKT_QUERY:
1604 object_init(prop);
1605 add_property_stringl(prop, "name", query->packet.data.query.name, query->packet.data.query.name_len, 1);
1606 add_property_long(prop, "type", query->packet.data.query.type);
1607 add_property_long(prop, "dnsclass", query->packet.data.query.dnsclass);
1608 add_property_zval(return_value, "query", prop);
1609 break;
1610
1611 case PHP_ARES_PCKT_SEND:
1612 ZVAL_STRINGL(prop, query->packet.data.send.buf, query->packet.data.send.len, 1);
1613 add_property_zval(return_value, "send", prop);
1614 break;
1615
1616 case PHP_ARES_PCKT_HNAME:
1617 object_init(prop);
1618 add_property_stringl(prop, "name", query->packet.data.hname.name, query->packet.data.hname.name_len, 1);
1619 add_property_long(prop, "family", query->packet.data.hname.family);
1620 add_property_zval(return_value, "gethostbyname", prop);
1621 break;
1622
1623 case PHP_ARES_PCKT_HADDR:
1624 object_init(prop);
1625 add_property_stringl(prop, "addr", query->packet.data.haddr.addr, query->packet.data.haddr.addr_len, 1);
1626 add_property_long(prop, "family", query->packet.data.haddr.family);
1627 add_property_zval(return_value, "gethostbyaddr", prop);
1628 break;
1629
1630 case PHP_ARES_PCKT_NINFO:
1631 object_init(prop);
1632 add_property_long(prop, "flags", query->packet.data.ninfo.flags);
1633 add_property_stringl(prop, "addr", query->packet.data.ninfo.addr, query->packet.data.ninfo.addr_len, 1);
1634 add_property_long(prop, "family", query->packet.data.ninfo.family);
1635 add_property_long(prop, "port", query->packet.data.ninfo.port);
1636 add_property_zval(return_value, "getnameinfo", prop);
1637 break;
1638 }
1639
1640 zval_ptr_dtor(&prop);
1641 }
1642 /* }}} */
1643
1644 #ifdef HAVE_ARES_CANCEL
1645 /* {{{ proto void ares_cancel(resource ares)
1646 Cancel pending queries */
1647 static PHP_FUNCTION(ares_cancel)
1648 {
1649 zval *rsrc;
1650 php_ares *ares;
1651
1652 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1653 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1654 ares_cancel(ares->channel);
1655 }
1656 }
1657 /* }}} */
1658 #endif
1659
1660 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1661 Process all pending queries */
1662 static PHP_FUNCTION(ares_process_all)
1663 {
1664 zval *rsrc;
1665 php_ares *ares;
1666 long max_timeout = -1;
1667
1668 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1669 RETURN_FALSE;
1670 }
1671 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1672
1673 while (php_ares_process(ares, max_timeout));
1674 }
1675 /* }}} */
1676
1677 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1678 Process once and return whether it should be called again */
1679 static PHP_FUNCTION(ares_process_once)
1680 {
1681 zval *rsrc;
1682 php_ares *ares;
1683 long max_timeout = -1;
1684
1685 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1686 RETURN_FALSE;
1687 }
1688 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1689
1690 RETVAL_BOOL(php_ares_process(ares, max_timeout));
1691 }
1692 /* }}} */
1693
1694 /* {{{ proto void ares_process(resource ares, array read, array write)
1695 Process call */
1696 static PHP_FUNCTION(ares_process)
1697 {
1698 zval *rsrc, *read = NULL, *write = NULL;
1699 fd_set R, W;
1700 php_ares *ares;
1701
1702 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a!a!", &rsrc, &read, &write)) {
1703 RETURN_FALSE;
1704 }
1705 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1706
1707 FD_ZERO(&R);
1708 FD_ZERO(&W);
1709
1710 php_ares_extract_fds(read, write, &R, &W, NULL TSRMLS_CC);
1711 ares_process(ares->channel, &R, &W);
1712 }
1713 /* }}} */
1714
1715 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1716 Select call */
1717 static PHP_FUNCTION(ares_select)
1718 {
1719 zval *read = NULL, *write = NULL;
1720 fd_set R, W;
1721 int nfds;
1722 long timeout;
1723 struct timeval tv;
1724 HashTable resource_map;
1725
1726 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aal", &read, &write, &timeout)) {
1727 RETURN_FALSE;
1728 }
1729
1730 if (timeout) {
1731 tv.tv_sec = timeout / 1000;
1732 tv.tv_usec = timeout % (timeout * 1000);
1733 } else {
1734 tv.tv_sec = 1;
1735 tv.tv_usec = 0;
1736 }
1737
1738 FD_ZERO(&R);
1739 FD_ZERO(&W);
1740
1741 zend_hash_init(&resource_map, zend_hash_num_elements(Z_ARRVAL_P(read) + zend_hash_num_elements(Z_ARRVAL_P(write))), NULL, ZVAL_PTR_DTOR, 0);
1742 nfds = php_ares_extract_fds(read, write, &R, &W, &resource_map TSRMLS_CC);
1743 if (-1 < select(nfds, &R, &W, NULL, &tv)) {
1744 zend_hash_clean(Z_ARRVAL_P(read));
1745 zend_hash_clean(Z_ARRVAL_P(write));
1746 php_ares_publish_fds(&R, &W, read, write, &resource_map);
1747 RETVAL_TRUE;
1748 } else {
1749 RETVAL_FALSE;
1750 }
1751 zend_hash_destroy(&resource_map);
1752 }
1753 /* }}} */
1754
1755 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1756 Get suggested select timeout in ms */
1757 static PHP_FUNCTION(ares_timeout)
1758 {
1759 zval *rsrc;
1760 long max_timeout = -1;
1761 struct timeval tv, *tvptr;
1762 php_ares *ares;
1763
1764 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1765 RETURN_FALSE;
1766 }
1767 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1768
1769 if ((tvptr = php_ares_timeout(ares, max_timeout, &tv))) {
1770 RETURN_LONG(tvptr->tv_sec * 1000 + tvptr->tv_usec / 1000);
1771 }
1772 RETURN_LONG(0);
1773 }
1774 /* }}} */
1775
1776 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1777 Get file descriptors */
1778 static PHP_FUNCTION(ares_fds)
1779 {
1780 zval *rsrc, *read, *write;
1781 fd_set R, W;
1782 php_ares *ares;
1783
1784 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzz", &rsrc, &read, &write)) {
1785 RETURN_FALSE;
1786 }
1787 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1788
1789 FD_ZERO(&R);
1790 FD_ZERO(&W);
1791
1792 zval_dtor(read);
1793 zval_dtor(write);
1794 array_init(read);
1795 array_init(write);
1796 ares_fds(ares->channel, &R, &W);
1797 RETVAL_LONG(php_ares_publish_fds(&R, &W, read, write, NULL));
1798 }
1799 /* }}} */
1800
1801 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor)
1802 {
1803 php_ares *ares = (php_ares *) rsrc->ptr;
1804
1805 ares_destroy(ares->channel);
1806 zend_llist_destroy(&ares->queries);
1807 php_ares_options_dtor(&ares->options);
1808 efree(ares);
1809 }
1810
1811 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor)
1812 {
1813 php_ares_query *query = (php_ares_query *) rsrc->ptr;
1814
1815 php_ares_query_dtor(query);
1816 efree(query);
1817 }
1818
1819 /* {{{ PHP_MINIT_FUNCTION */
1820 static PHP_MINIT_FUNCTION(ares)
1821 {
1822 #ifdef HAVE_ARES_LIBRARY_INIT
1823 if (ARES_SUCCESS != ares_library_init(ARES_LIB_INIT_ALL)) {
1824 return FAILURE;
1825 }
1826 #endif
1827 #ifdef HAVE_ARES_VERSION
1828 {
1829 int ares_version_num;
1830 ares_version(&ares_version_num);
1831
1832 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
1833 }
1834 #endif
1835
1836 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS, CONST_PERSISTENT|CONST_CS);
1837 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA, CONST_PERSISTENT|CONST_CS);
1838 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR, CONST_PERSISTENT|CONST_CS);
1839 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL, CONST_PERSISTENT|CONST_CS);
1840 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND, CONST_PERSISTENT|CONST_CS);
1841 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP, CONST_PERSISTENT|CONST_CS);
1842 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED, CONST_PERSISTENT|CONST_CS);
1843 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY, CONST_PERSISTENT|CONST_CS);
1844 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME, CONST_PERSISTENT|CONST_CS);
1845 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY, CONST_PERSISTENT|CONST_CS);
1846 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP, CONST_PERSISTENT|CONST_CS);
1847 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED, CONST_PERSISTENT|CONST_CS);
1848 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT, CONST_PERSISTENT|CONST_CS);
1849 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF, CONST_PERSISTENT|CONST_CS);
1850 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE, CONST_PERSISTENT|CONST_CS);
1851 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM, CONST_PERSISTENT|CONST_CS);
1852 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION, CONST_PERSISTENT|CONST_CS);
1853 #ifdef ARES_EBADSTR
1854 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR, CONST_PERSISTENT|CONST_CS);
1855 #endif
1856 #ifdef ARES_EBADFLAGS
1857 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS, CONST_PERSISTENT|CONST_CS);
1858 #endif
1859 #ifdef ARES_ENONAME
1860 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME, CONST_PERSISTENT|CONST_CS);
1861 #endif
1862 #ifdef ARES_EBADHINTS
1863 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS, CONST_PERSISTENT|CONST_CS);
1864 #endif
1865 #ifdef ARES_ENOTINITIALIZED
1866 REGISTER_LONG_CONSTANT("ARES_ENOTINITIALIZED", ARES_ENOTINITIALIZED, CONST_PERSISTENT|CONST_CS);
1867 #endif
1868 #ifdef ARES_ELOADIPHLPAPI
1869 REGISTER_LONG_CONSTANT("ARES_ELOADIPHLPAPI", ARES_ELOADIPHLPAPI, CONST_PERSISTENT|CONST_CS);
1870 #endif
1871 #ifdef ARES_EADDRGETNETWORKPARAMS
1872 REGISTER_LONG_CONSTANT("ARES_EADDRGETNETWORKPARAMS", ARES_EADDRGETNETWORKPARAMS, CONST_PERSISTENT|CONST_CS);
1873 #endif
1874 #ifdef ARES_ECANCELLED
1875 REGISTER_LONG_CONSTANT("ARES_ECANCELLED", ARES_ECANCELLED, CONST_PERSISTENT|CONST_CS);
1876 #endif
1877
1878 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC, CONST_PERSISTENT|CONST_CS);
1879 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY, CONST_PERSISTENT|CONST_CS);
1880 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC, CONST_PERSISTENT|CONST_CS);
1881 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE, CONST_PERSISTENT|CONST_CS);
1882 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN, CONST_PERSISTENT|CONST_CS);
1883 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH, CONST_PERSISTENT|CONST_CS);
1884 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES, CONST_PERSISTENT|CONST_CS);
1885 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP, CONST_PERSISTENT|CONST_CS);
1886 #ifdef ARES_FLAG_EDNS
1887 REGISTER_LONG_CONSTANT("ARES_FLAG_EDNS", ARES_FLAG_EDNS, CONST_PERSISTENT|CONST_CS);
1888 #endif
1889
1890 /*
1891 * Address Family Constants
1892 */
1893 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET, CONST_PERSISTENT|CONST_CS);
1894 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6, CONST_PERSISTENT|CONST_CS);
1895
1896 /*
1897 * Name Info constants
1898 */
1899 #ifdef ARES_NI_NOFQDN
1900 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN, CONST_PERSISTENT|CONST_CS);
1901 #endif
1902 #ifdef ARES_NI_NUMERICHOST
1903 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1904 #endif
1905 #ifdef ARES_NI_NAMEREQD
1906 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD, CONST_PERSISTENT|CONST_CS);
1907 #endif
1908 #ifdef ARES_NI_NUMERICSERV
1909 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1910 #endif
1911 #ifdef ARES_NI_DGRAM
1912 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM, CONST_PERSISTENT|CONST_CS);
1913 #endif
1914 #ifdef ARES_NI_TCP
1915 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP, CONST_PERSISTENT|CONST_CS);
1916 #endif
1917 #ifdef ARES_NI_UDP
1918 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP, CONST_PERSISTENT|CONST_CS);
1919 #endif
1920 #ifdef ARES_NI_SCTP
1921 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP, CONST_PERSISTENT|CONST_CS);
1922 #endif
1923 #ifdef ARES_NI_DCCP
1924 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP, CONST_PERSISTENT|CONST_CS);
1925 #endif
1926 #ifdef ARES_NI_NUMERICSCOPE
1927 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE, CONST_PERSISTENT|CONST_CS);
1928 #endif
1929 #ifdef ARES_NI_LOOKUPHOST
1930 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST, CONST_PERSISTENT|CONST_CS);
1931 #endif
1932 #ifdef ARES_NI_LOOKUPSERVICE
1933 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE, CONST_PERSISTENT|CONST_CS);
1934 #endif
1935 #ifdef ARES_NI_IDN
1936 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN, CONST_PERSISTENT|CONST_CS);
1937 #endif
1938 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1939 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1940 #endif
1941 #ifdef ARES_NI_IDN_USE_STD
1942 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1943 #endif
1944
1945 /*
1946 * Address Info constants
1947 */
1948 #ifdef ARES_AI_CANONNAME
1949 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME, CONST_PERSISTENT|CONST_CS);
1950 #endif
1951 #ifdef ARES_AI_NUMERICHOST
1952 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1953 #endif
1954 #ifdef ARES_AI_PASSIVE
1955 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE, CONST_PERSISTENT|CONST_CS);
1956 #endif
1957 #ifdef ARES_AI_NUMERICSERV
1958 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1959 #endif
1960 #ifdef ARES_AI_V
1961 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V, CONST_PERSISTENT|CONST_CS);
1962 #endif
1963 #ifdef ARES_AI_ALL
1964 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL, CONST_PERSISTENT|CONST_CS);
1965 #endif
1966 #ifdef ARES_AI_ADDRCONFIG
1967 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG, CONST_PERSISTENT|CONST_CS);
1968 #endif
1969 #ifdef ARES_AI_IDN
1970 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN, CONST_PERSISTENT|CONST_CS);
1971 #endif
1972 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1973 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1974 #endif
1975 #ifdef ARES_AI_IDN_USE_STD
1976 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1977 #endif
1978 #ifdef ARES_AI_CANONIDN
1979 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN, CONST_PERSISTENT|CONST_CS);
1980 #endif
1981 #ifdef ARES_AI_MASK
1982 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK, CONST_PERSISTENT|CONST_CS);
1983 #endif
1984 #ifdef ARES_GETSOCK_MAXNUM
1985 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM, CONST_PERSISTENT|CONST_CS);
1986 #endif
1987
1988 /*
1989 * ns_t (type) constants (arpa/nameser.h)
1990 */
1991 #ifdef T_A
1992 /* (1) Host address. */
1993 REGISTER_LONG_CONSTANT("ARES_T_A", T_A, CONST_CS|CONST_PERSISTENT);
1994 #endif
1995 #ifdef T_NS
1996 /* (2) Authoritative server. */
1997 REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS, CONST_CS|CONST_PERSISTENT);
1998 #endif
1999 #ifdef T_MD
2000 /* (3) Mail destination. */
2001 REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD, CONST_CS|CONST_PERSISTENT);
2002 #endif
2003 #ifdef T_MF
2004 /* (4) Mail forwarder. */
2005 REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF, CONST_CS|CONST_PERSISTENT);
2006 #endif
2007 #ifdef T_CNAME
2008 /* (5) Canonical name. */
2009 REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME, CONST_CS|CONST_PERSISTENT);
2010 #endif
2011 #ifdef T_SOA
2012 /* (6) Start of authority zone. */
2013 REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA, CONST_CS|CONST_PERSISTENT);
2014 #endif
2015 #ifdef T_MB
2016 /* (7) Mailbox domain name. */
2017 REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB, CONST_CS|CONST_PERSISTENT);
2018 #endif
2019 #ifdef T_MG
2020 /* (8) Mail group member. */
2021 REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG, CONST_CS|CONST_PERSISTENT);
2022 #endif
2023 #ifdef T_MR
2024 /* (9) Mail rename name. */
2025 REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR, CONST_CS|CONST_PERSISTENT);
2026 #endif
2027 #ifdef T_NULL
2028 /* (10) Null resource record. */
2029 REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL, CONST_CS|CONST_PERSISTENT);
2030 #endif
2031 #ifdef T_WKS
2032 /* (11) Well known service. */
2033 REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS, CONST_CS|CONST_PERSISTENT);
2034 #endif
2035 #ifdef T_PTR
2036 /* (12) Domain name pointer. */
2037 REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR, CONST_CS|CONST_PERSISTENT);
2038 #endif
2039 #ifdef T_HINFO
2040 /* (13) Host information. */
2041 REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO, CONST_CS|CONST_PERSISTENT);
2042 #endif
2043 #ifdef T_MINFO
2044 /* (14) Mailbox information. */
2045 REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO, CONST_CS|CONST_PERSISTENT);
2046 #endif
2047 #ifdef T_MX
2048 /* (15) Mail routing information. */
2049 REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX, CONST_CS|CONST_PERSISTENT);
2050 #endif
2051 #ifdef T_TXT
2052 /* (16) Text strings. */
2053 REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT, CONST_CS|CONST_PERSISTENT);
2054 #endif
2055 #ifdef T_RP
2056 /* (17) Responsible person. */
2057 REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP, CONST_CS|CONST_PERSISTENT);
2058 #endif
2059 #ifdef T_AFSDB
2060 /* (18) AFS cell database. */
2061 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB, CONST_CS|CONST_PERSISTENT);
2062 #endif
2063 #ifdef T_X25
2064 /* (19) X_25 calling address. */
2065 REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25, CONST_CS|CONST_PERSISTENT);
2066 #endif
2067 #ifdef T_ISDN
2068 /* (20) ISDN calling address. */
2069 REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN, CONST_CS|CONST_PERSISTENT);
2070 #endif
2071 #ifdef T_RT
2072 /* (21) Router. */
2073 REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT, CONST_CS|CONST_PERSISTENT);
2074 #endif
2075 #ifdef T_NSAP
2076 /* (22) NSAP address. */
2077 REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP, CONST_CS|CONST_PERSISTENT);
2078 #endif
2079 #ifdef T_NSAP_PTR
2080 /* (23) Reverse NSAP lookup (deprecated). */
2081 REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR, CONST_CS|CONST_PERSISTENT);
2082 #endif
2083 #ifdef T_SIG
2084 /* (24) Security signature. */
2085 REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG, CONST_CS|CONST_PERSISTENT);
2086 #endif
2087 #ifdef T_KEY
2088 /* (25) Security key. */
2089 REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY, CONST_CS|CONST_PERSISTENT);
2090 #endif
2091 #ifdef T_PX
2092 /* (26) X.400 mail mapping. */
2093 REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX, CONST_CS|CONST_PERSISTENT);
2094 #endif
2095 #ifdef T_GPOS
2096 /* (27) Geographical position (withdrawn). */
2097 REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS, CONST_CS|CONST_PERSISTENT);
2098 #endif
2099 #ifdef T_AAAA
2100 /* (28) Ip6 Address. */
2101 REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA, CONST_CS|CONST_PERSISTENT);
2102 #endif
2103 #ifdef T_LOC
2104 /* (29) Location Information. */
2105 REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC, CONST_CS|CONST_PERSISTENT);
2106 #endif
2107 #ifdef T_NXT
2108 /* (30) Next domain (security). */
2109 REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT, CONST_CS|CONST_PERSISTENT);
2110 #endif
2111 #ifdef T_EID
2112 /* (31) Endpoint identifier. */
2113 REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID, CONST_CS|CONST_PERSISTENT);
2114 #endif
2115 #ifdef T_NIMLOC
2116 /* (32) Nimrod Locator. */
2117 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC, CONST_CS|CONST_PERSISTENT);
2118 #endif
2119 #ifdef T_SRV
2120 /* (33) Server Selection. */
2121 REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV, CONST_CS|CONST_PERSISTENT);
2122 #endif
2123 #ifdef T_ATMA
2124 /* (34) ATM Address */
2125 REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA, CONST_CS|CONST_PERSISTENT);
2126 #endif
2127 #ifdef T_NAPTR
2128 /* (35) Naming Authority Pointer */
2129 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR, CONST_CS|CONST_PERSISTENT);
2130 #endif
2131 #ifdef T_KX
2132 /* (36) Key Exchange */
2133 REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX, CONST_CS|CONST_PERSISTENT);
2134 #endif
2135 #ifdef T_CERT
2136 /* (37) Certification record */
2137 REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT, CONST_CS|CONST_PERSISTENT);
2138 #endif
2139 #ifdef T_A6
2140 /* (38) IPv6 address (deprecates AAAA) */
2141 REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6, CONST_CS|CONST_PERSISTENT);
2142 #endif
2143 #ifdef T_DNAME
2144 /* (39) Non-terminal DNAME (for IPv6) */
2145 REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME, CONST_CS|CONST_PERSISTENT);
2146 #endif
2147 #ifdef T_SINK
2148 /* (40) Kitchen sink (experimentatl) */
2149 REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK, CONST_CS|CONST_PERSISTENT);
2150 #endif
2151 #ifdef T_OPT
2152 /* (41) EDNS0 option (meta-RR) */
2153 REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT, CONST_CS|CONST_PERSISTENT);
2154 #endif
2155 #ifdef T_TSIG
2156 /* (250) Transaction signature. */
2157 REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG, CONST_CS|CONST_PERSISTENT);
2158 #endif
2159 #ifdef T_IXFR
2160 /* (251) Incremental zone transfer. */
2161 REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR, CONST_CS|CONST_PERSISTENT);
2162 #endif
2163 #ifdef T_AXFR
2164 /* (252) Transfer zone of authority. */
2165 REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR, CONST_CS|CONST_PERSISTENT);
2166 #endif
2167 #ifdef T_MAILB
2168 /* (253) Transfer mailbox records. */
2169 REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB, CONST_CS|CONST_PERSISTENT);
2170 #endif
2171 #ifdef T_MAILA
2172 /* (254) Transfer mail agent records. */
2173 REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA, CONST_CS|CONST_PERSISTENT);
2174 #endif
2175 #ifdef T_ANY
2176 /* (255) Wildcard match. */
2177 REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY, CONST_CS|CONST_PERSISTENT);
2178 #endif
2179
2180 /*
2181 * ns_c (dnsclass) constants (arpa/nameser.h)
2182 */
2183
2184 #ifdef C_IN
2185 /* (1) Internet. */
2186 REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN, CONST_CS|CONST_PERSISTENT);
2187 #endif
2188 #ifdef C_2
2189 /* (2) unallocated/unsupported. */
2190 REGISTER_LONG_CONSTANT("ARES_C_2", C_2, CONST_CS|CONST_PERSISTENT);
2191 #endif
2192 #ifdef C_CHAOS
2193 /* (3) MIT Chaos-net. */
2194 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS, CONST_CS|CONST_PERSISTENT);
2195 #endif
2196 #ifdef C_HS
2197 /* (4) MIT Hesiod. */
2198 REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS, CONST_CS|CONST_PERSISTENT);
2199 #endif
2200 #ifdef C_NONE
2201 /* (254) for prereq. sections in update requests */
2202 REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE, CONST_CS|CONST_PERSISTENT);
2203 #endif
2204 #ifdef C_ANY
2205 /* (255) Wildcard match. */
2206 REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY, CONST_CS|CONST_PERSISTENT);
2207 #endif
2208
2209 le_ares = zend_register_list_destructors_ex(php_ares_le_dtor, NULL, PHP_ARES_LE_NAME, module_number);
2210 le_ares_query = zend_register_list_destructors_ex(php_ares_query_le_dtor, NULL, PHP_ARES_QUERY_LE_NAME, module_number);
2211
2212 return SUCCESS;
2213 }
2214 /* }}} */
2215
2216 /* {{{ PHP_MSHUTDOWN_FUNCTION */
2217 static PHP_MSHUTDOWN_FUNCTION(ares)
2218 {
2219 #ifdef HAVE_ARES_LIBRARY_CLEANUP
2220 ares_library_cleanup();
2221 #endif
2222 return SUCCESS;
2223 }
2224 /* }}} */
2225
2226 /* {{{ PHP_MINFO_FUNCTION */
2227 static PHP_MINFO_FUNCTION(ares)
2228 {
2229 php_info_print_table_start();
2230 php_info_print_table_header(2, "AsyncResolver support", "enabled");
2231 php_info_print_table_row(2, "Version", PHP_ARES_VERSION);
2232 php_info_print_table_end();
2233
2234 php_info_print_table_start();
2235 php_info_print_table_header(3, "Used Library", "compiled", "linked");
2236 php_info_print_table_row(3,
2237 PHP_ARES_LIBNAME,
2238 #ifdef ARES_VERSION_STR
2239 ARES_VERSION_STR,
2240 #else
2241 "unkown",
2242 #endif
2243 #ifdef HAVE_ARES_VERSION
2244 ares_version(NULL)
2245 #else
2246 "unkown"
2247 #endif
2248 );
2249 php_info_print_table_end();
2250 }
2251 /* }}} */
2252
2253 #ifdef ZEND_ENGINE_2
2254 ZEND_BEGIN_ARG_INFO(ai_ares_select, 0)
2255 ZEND_ARG_PASS_INFO(1)
2256 ZEND_ARG_PASS_INFO(1)
2257 ZEND_ARG_PASS_INFO(0)
2258 ZEND_END_ARG_INFO();
2259
2260 ZEND_BEGIN_ARG_INFO(ai_ares_result, 0)
2261 ZEND_ARG_PASS_INFO(0)
2262 ZEND_ARG_PASS_INFO(1)
2263 ZEND_ARG_PASS_INFO(1)
2264 ZEND_END_ARG_INFO();
2265
2266 ZEND_BEGIN_ARG_INFO(ai_ares_fds, 0)
2267 ZEND_ARG_PASS_INFO(0)
2268 ZEND_ARG_PASS_INFO(1)
2269 ZEND_ARG_PASS_INFO(1)
2270 ZEND_END_ARG_INFO();
2271 #else
2272 static unsigned char ai_ares_select[] = {3, BYREF_FORCE, BYREF_FORCE, BYREF_NONE};
2273 static unsigned char ai_ares_result[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2274 static unsigned char ai_ares_fds[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2275 #endif
2276
2277 /* {{{ ares_functions[] */
2278 zend_function_entry ares_functions[] = {
2279 #ifdef HAVE_ARES_VERSION
2280 PHP_FE(ares_version, NULL)
2281 #endif
2282 PHP_FE(ares_init, NULL)
2283 PHP_FE(ares_destroy, NULL)
2284 PHP_FE(ares_strerror, NULL)
2285 #ifdef HAVE_ARES_CANCEL
2286 PHP_FE(ares_cancel, NULL)
2287 #endif
2288 PHP_FE(ares_search, NULL)
2289 PHP_FE(ares_query, NULL)
2290 PHP_FE(ares_send, NULL)
2291 PHP_FE(ares_mkquery, NULL)
2292 PHP_FE(ares_gethostbyname, NULL)
2293 PHP_FE(ares_gethostbyaddr, NULL)
2294 #ifdef HAVE_ARES_GETNAMEINFO
2295 PHP_FE(ares_getnameinfo, NULL)
2296 #endif
2297 PHP_FE(ares_result, ai_ares_result)
2298 PHP_FE(ares_packet, NULL)
2299 PHP_FE(ares_process_all, NULL)
2300 PHP_FE(ares_process_once, NULL)
2301 PHP_FE(ares_process, NULL)
2302 PHP_FE(ares_select, ai_ares_select)
2303 PHP_FE(ares_fds, ai_ares_fds)
2304 PHP_FE(ares_timeout, NULL)
2305 #ifdef HAVE_ARES_SET_LOCAL_DEV
2306 PHP_FE(ares_set_local_dev, NULL)
2307 #endif
2308 #ifdef HAVE_ARES_SET_LOCAL_IP4
2309 PHP_FE(ares_set_local_ip4, NULL)
2310 #endif
2311 #ifdef HAVE_ARES_SET_LOCAL_IP6
2312 PHP_FE(ares_set_local_ip6, NULL)
2313 #endif
2314 {NULL, NULL, NULL}
2315 };
2316 /* }}} */
2317
2318 /* {{{ ares_module_entry */
2319 zend_module_entry ares_module_entry = {
2320 STANDARD_MODULE_HEADER,
2321 "ares",
2322 ares_functions,
2323 PHP_MINIT(ares),
2324 PHP_MSHUTDOWN(ares),
2325 NULL,
2326 NULL,
2327 PHP_MINFO(ares),
2328 PHP_ARES_VERSION,
2329 STANDARD_MODULE_PROPERTIES
2330 };
2331 /* }}} */
2332
2333 #ifdef COMPILE_DL_ARES
2334 ZEND_GET_MODULE(ares)
2335 #endif
2336
2337 /*
2338 * Local variables:
2339 * tab-width: 4
2340 * c-basic-offset: 4
2341 * End:
2342 * vim600: noet sw=4 ts=4 fdm=marker
2343 * vim<600: noet sw=4 ts=4
2344 */