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