ares already does htons()
[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 options->strct.udp_port = (unsigned short) lval;
557 }
558 if ((SUCCESS == zend_hash_find(ht, "tcp_port", sizeof("tcp_port"), (void *) &opt)) && is_numeric(opt, &lval)) {
559 options->flags |= ARES_OPT_TCP_PORT;
560 options->strct.tcp_port = (unsigned short) lval;
561 }
562 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)))) {
563 options->strct.servers = ecalloc(i, sizeof(struct in_addr));
564 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
565 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
566 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
567 if (Z_TYPE_PP(entry) == IS_STRING) {
568 inet_aton(Z_STRVAL_PP(entry), &options->strct.servers[options->strct.nservers++]);
569 }
570 }
571 if (options->strct.nservers) {
572 options->flags |= ARES_OPT_SERVERS;
573 }
574 }
575 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)))) {
576 options->strct.domains = ecalloc(i, sizeof(char *));
577 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
578 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
579 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
580 if (Z_TYPE_PP(entry) == IS_STRING) {
581 options->strct.domains[options->strct.ndomains++] = estrdup(Z_STRVAL_PP(entry));
582 }
583 }
584 if (options->strct.ndomains) {
585 options->flags |= ARES_OPT_DOMAINS;
586 }
587 }
588 if ((SUCCESS == zend_hash_find(ht, "lookups", sizeof("lookups"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_STRING)) {
589 options->flags |= ARES_OPT_LOOKUPS;
590 options->strct.lookups = estrdup(Z_STRVAL_PP(opt));
591 }
592 #ifdef ARES_OPT_ROTATE
593 if ((SUCCESS == zend_hash_find(ht, "rotate", sizeof("rotate"), (void *) &opt)) && i_zend_is_true(*opt)) {
594 options->flags |= ARES_OPT_ROTATE;
595 }
596 #endif
597 #ifdef ARES_OPT_EDNSPSZ
598 if ((SUCCESS == zend_hash_find(ht, "ednspsz", sizeof("ednspsz"), (void *) &opt)) && is_numeric(opt, &lval)) {
599 options->flags |= ARES_OPT_EDNSPSZ;
600 options->strct.ednspsz = lval;
601 }
602 #endif
603 }
604
605 return options;
606 }
607 /* }}} */
608
609 local void php_ares_options_dtor(php_ares_options *options) /* {{{ */
610 {
611 int i;
612
613 if (options->strct.servers) {
614 efree(options->strct.servers);
615 }
616
617 if (options->strct.domains) {
618 for (i = 0; i < options->strct.ndomains; ++i) {
619 efree(options->strct.domains[i]);
620 }
621 efree(options->strct.domains);
622 }
623
624 STR_FREE(options->strct.lookups);
625
626 memset(options, 0, sizeof(php_ares_options));
627 }
628 /* }}} */
629
630 local void php_ares_options_free(php_ares_options **options) /* {{{ */
631 {
632 php_ares_options_dtor(*options);
633 efree(*options);
634 *options = NULL;
635 }
636 /* }}} */
637
638 local PHP_ARES_EXPAND_LEN_TYPE php_ares_skip(const unsigned char *pointer, const unsigned char *abuf, int alen TSRMLS_DC)
639 {
640 char *name;
641 int rc;
642 PHP_ARES_EXPAND_LEN_TYPE byte_count;
643
644 /* NOTE: byte_count is not neccessarily the length of the string,
645 i.e. if there were back references */
646 if (ARES_SUCCESS == (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
647 /*fprintf(stderr, "-- skipping %s\n", name);*/
648 ares_free_string(name);
649 return byte_count;
650 }
651 PHP_ARES_ERROR(rc);
652 return -1;
653 }
654
655 local int php_ares_parse(const unsigned char *abuf, int alen, zval *result TSRMLS_DC) /* {{{ */
656 {
657 HEADER *header;
658 PHP_ARES_EXPAND_LEN_TYPE byte_count;
659 const unsigned char *pointer;
660 char *name;
661 int rc, query_count, answer_count;
662
663 convert_to_array(result);
664
665 if (!alen || !abuf || !*abuf) {
666 return SUCCESS;
667 }
668
669 header = (HEADER *) abuf;
670 pointer = abuf + HFIXEDSZ;
671
672 for (query_count = ntohs(header->qdcount); query_count--; pointer += byte_count + QFIXEDSZ) {
673 if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
674 return FAILURE;
675 }
676 }
677
678 for (answer_count = ntohs(header->ancount); answer_count-- && pointer < (abuf + alen); ) {
679 uint16_t stmp, type, class;
680 uint32_t ltmp, ttl;
681 zval **entry_ptr, *entry = NULL;
682
683 if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
684 return FAILURE;
685 }
686
687 pointer += byte_count;
688
689 MAKE_STD_ZVAL(entry);
690 array_init(entry);
691
692 GETSHORT(type, pointer);
693 add_assoc_string(entry, "type", estrdup(php_ares_T_names[type]), 0);
694 GETSHORT(class, pointer);
695 add_assoc_string(entry, "class", estrdup(php_ares_C_names[class]), 0);
696 GETLONG(ttl, pointer);
697 add_assoc_long(entry, "ttl", ttl);
698 GETSHORT(byte_count, pointer);
699 #if 0
700 fprintf(stderr, ">> processing %s answer of length %d\n", php_ares_T_names[type], byte_count);
701 #endif
702 switch (type) {
703 case T_A:
704 spprintf(&name, 0, "%d.%d.%d.%d", pointer[0], pointer[1], pointer[2], pointer[3]);
705 add_assoc_string(entry, "addr", name, 0);
706 pointer += byte_count;
707 break;
708
709 case T_NS:
710 case T_PTR:
711 case T_CNAME:
712 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
713 PHP_ARES_ERROR(rc);
714 return FAILURE;
715 }
716 pointer += byte_count;
717 add_assoc_string(entry, "name", name, 1);
718 ares_free_string(name);
719 break;
720
721 case T_MX:
722 GETSHORT(stmp, pointer);
723 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
724 PHP_ARES_ERROR(rc);
725 return FAILURE;
726 }
727 pointer += byte_count;
728 add_assoc_long(entry, "weight", stmp);
729 add_assoc_string(entry, "name", name, 1);
730 ares_free_string(name);
731 break;
732
733 case T_SRV:
734 GETSHORT(stmp, pointer);
735 add_assoc_long(entry, "priority", stmp);
736 GETSHORT(stmp, pointer);
737 add_assoc_long(entry, "weight", stmp);
738 GETSHORT(stmp, pointer);
739 add_assoc_long(entry, "port", stmp);
740
741 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
742 PHP_ARES_ERROR(rc);
743 zval_ptr_dtor(&entry);
744 return FAILURE;
745 }
746 pointer += byte_count;
747 add_assoc_string(entry, "name", name, 1);
748 ares_free_string(name);
749 break;
750
751 case T_SOA:
752 if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
753 PHP_ARES_ERROR(rc);
754 zval_ptr_dtor(&entry);
755 return FAILURE;
756 }
757 pointer += byte_count;
758 add_assoc_string(entry, "name", name, 1);
759 ares_free_string(name);
760
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, "mail", name, 1);
768 ares_free_string(name);
769
770 GETLONG(ltmp, pointer);
771 add_assoc_long(entry, "serial", ltmp);
772 GETLONG(ltmp, pointer);
773 add_assoc_long(entry, "refresh", ltmp);
774 GETLONG(ltmp, pointer);
775 add_assoc_long(entry, "retry", ltmp);
776 GETLONG(ltmp, pointer);
777 add_assoc_long(entry, "expire", ltmp);
778 GETLONG(ltmp, pointer);
779 add_assoc_long(entry, "minimum-ttl", ltmp);
780 break;
781
782 case T_TXT:
783 for (ltmp = 0; ltmp < byte_count; ltmp += pointer[ltmp] + 1) {
784 add_next_index_stringl(entry, (const char *) &pointer[ltmp + 1], pointer[ltmp], 1);
785 }
786 pointer += byte_count;
787 break;
788
789 default:
790 zval_ptr_dtor(&entry);
791 entry = NULL;
792 pointer += byte_count;
793 break;
794 }
795
796 if (entry) {
797 add_next_index_zval(result, entry);
798 }
799 }
800
801 return SUCCESS;
802 }
803 /* }}} */
804
805 /* {{{ callbacks */
806 static void php_ares_callback_func_old(void *aq, int status, unsigned char *abuf, int alen)
807 {
808 php_ares_query *q = (php_ares_query *) aq;
809 zval *params[4], *retval, *parsed = NULL;
810 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
811
812 q->error = status;
813 if (abuf) {
814 q->result.std.buf = estrndup((char *) abuf, alen);
815 q->result.std.len = alen;
816
817 MAKE_STD_ZVAL(parsed);
818 ZVAL_NULL(parsed);
819 if (SUCCESS == php_ares_parse(abuf, alen, parsed)) {
820 q->result.std.arr = parsed;
821 } else {
822 zval_ptr_dtor(&parsed);
823 parsed = NULL;
824 }
825 }
826
827 if (q->callback) {
828 MAKE_STD_ZVAL(retval);
829 MAKE_STD_ZVAL(params[0]);
830 MAKE_STD_ZVAL(params[1]);
831 MAKE_STD_ZVAL(params[2]);
832 ZVAL_NULL(retval);
833 zend_list_addref(q->id);
834 Z_LVAL_P(params[0]) = q->id;
835 Z_TYPE_P(params[0]) = IS_RESOURCE;
836 ZVAL_LONG(params[1], status);
837 ZVAL_STRINGL(params[2], (char *) abuf, alen, 1);
838
839 if (parsed) {
840 ADDREF(parsed);
841 params[3] = parsed;
842 }
843
844 q->ares->in_callback = 1;
845 call_user_function(EG(function_table), NULL, q->callback, retval, parsed ? 4 : 3, params TSRMLS_CC);
846 q->ares->in_callback = 0;
847
848 zval_ptr_dtor(&retval);
849 zval_ptr_dtor(&params[0]);
850 zval_ptr_dtor(&params[1]);
851 zval_ptr_dtor(&params[2]);
852
853 if (parsed) {
854 zval_ptr_dtor(&params[3]);
855 }
856 }
857 }
858
859 static void php_ares_host_callback_func_old(void *aq, int status, struct hostent *hostent)
860 {
861 php_ares_query *q = (php_ares_query *) aq;
862 zval *params[3], *retval;
863 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
864
865 q->error = status;
866 if (hostent) {
867 php_ares_hostent_copy(hostent, &q->result.host);
868 }
869
870 if (q->callback) {
871 MAKE_STD_ZVAL(retval);
872 MAKE_STD_ZVAL(params[0]);
873 MAKE_STD_ZVAL(params[1]);
874 MAKE_STD_ZVAL(params[2]);
875 ZVAL_NULL(retval);
876 zend_list_addref(q->id);
877 Z_LVAL_P(params[0]) = q->id;
878 Z_TYPE_P(params[0]) = IS_RESOURCE;
879 ZVAL_LONG(params[1], status);
880 object_init(params[2]);
881 php_ares_hostent_to_struct(hostent, HASH_OF(params[2]));
882
883 q->ares->in_callback = 1;
884 call_user_function(EG(function_table), NULL, q->callback, retval, 3, params TSRMLS_CC);
885 q->ares->in_callback = 0;
886
887 zval_ptr_dtor(&retval);
888 zval_ptr_dtor(&params[0]);
889 zval_ptr_dtor(&params[1]);
890 zval_ptr_dtor(&params[2]);
891 }
892 }
893
894 #ifdef HAVE_ARES_GETNAMEINFO
895 static void php_ares_nameinfo_callback_func_old(void *aq, int status, char *node, char *service)
896 {
897 php_ares_query *q = (php_ares_query *) aq;
898 zval *params[4], *retval;
899 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
900
901 q->error = status;
902 if (node) {
903 q->result.ninfo.node = estrdup(node);
904 }
905 if (service) {
906 q->result.ninfo.service = estrdup(service);
907 }
908
909 if (q->callback) {
910 MAKE_STD_ZVAL(retval);
911 MAKE_STD_ZVAL(params[0]);
912 MAKE_STD_ZVAL(params[1]);
913 MAKE_STD_ZVAL(params[2]);
914 MAKE_STD_ZVAL(params[3]);
915 ZVAL_NULL(retval);
916 zend_list_addref(q->id);
917 Z_LVAL_P(params[0]) = q->id;
918 Z_TYPE_P(params[0]) = IS_RESOURCE;
919 ZVAL_LONG(params[1], status);
920 if (node) {
921 ZVAL_STRING(params[2], node, 1);
922 } else {
923 ZVAL_NULL(params[2]);
924 }
925 if (service) {
926 ZVAL_STRING(params[3], service, 1);
927 } else {
928 ZVAL_NULL(params[3]);
929 }
930
931 q->ares->in_callback = 1;
932 call_user_function(EG(function_table), NULL, q->callback, retval, 4, params TSRMLS_CC);
933 q->ares->in_callback = 0;
934
935 zval_ptr_dtor(&retval);
936 zval_ptr_dtor(&params[0]);
937 zval_ptr_dtor(&params[1]);
938 zval_ptr_dtor(&params[2]);
939 zval_ptr_dtor(&params[3]);
940 }
941 }
942 #endif
943
944 #if PHP_ARES_NEW_CALLBACK_API
945 # define php_ares_callback_func php_ares_callback_func_new
946 static void php_ares_callback_func_new(void *aq, int status, int timeouts, unsigned char *abuf, int alen)
947 {
948 php_ares_callback_func_old(aq, status, abuf, alen);
949 }
950
951 # define php_ares_host_callback_func php_ares_host_callback_func_new
952 static void php_ares_host_callback_func_new(void *aq, int status, int timeouts, struct hostent *hostent)
953 {
954 php_ares_host_callback_func_old(aq, status, hostent);
955 }
956
957 # ifdef HAVE_ARES_GETNAMEINFO
958 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
959 static void php_ares_nameinfo_callback_func_new(void *aq, int status, int timeouts, char *node, char *service)
960 {
961 php_ares_nameinfo_callback_func_old(aq, status, node, service);
962 }
963 # endif
964
965 #else
966 # define php_ares_callback_func php_ares_callback_func_old
967 # define php_ares_host_callback_func php_ares_host_callback_func_old
968 # ifdef HAVE_ARES_GETNAMEINFO
969 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
970 # endif
971 #endif
972 /* }}} */
973
974 local struct timeval *php_ares_timeout(php_ares *ares, long max_timeout, struct timeval *tv_buf) /* {{{ */
975 {
976 struct timeval maxtv;
977
978 if (max_timeout > -1) {
979 maxtv.tv_sec = max_timeout / 1000;
980 maxtv.tv_usec = max_timeout % (max_timeout * 1000);
981 }
982
983 return ares_timeout(ares->channel, max_timeout > -1 ? &maxtv : NULL, tv_buf);
984 }
985 /* }}} */
986
987 local int php_ares_process(php_ares *ares, long max_timeout) /* {{{ */
988 {
989 int nfds;
990 fd_set R, W;
991 struct timeval tv;
992
993 FD_ZERO(&R);
994 FD_ZERO(&W);
995
996 if ((nfds = ares_fds(ares->channel, &R, &W))) {
997 if (0 < select(nfds, &R, &W, NULL, php_ares_timeout(ares, max_timeout, &tv))) {
998 ares_process(ares->channel, &R, &W);
999 }
1000 }
1001
1002 return nfds;
1003 }
1004 /* }}} */
1005
1006 local int php_ares_publish_fds(fd_set *R, fd_set *W, zval *r, zval *w) /* {{{ */
1007 {
1008 int i, nfds = 0;
1009
1010 for (i = 0; i < FD_SETSIZE; ++i) {
1011 if (FD_ISSET(i, R)) {
1012 add_next_index_long(r, i);
1013 if (i > nfds) {
1014 nfds = i;
1015 }
1016 }
1017 }
1018
1019 for (i = 0; i < FD_SETSIZE; ++i) {
1020 if (FD_ISSET(i, W)) {
1021 add_next_index_long(w, i);
1022 if (i > nfds) {
1023 nfds = i;
1024 }
1025 }
1026 }
1027
1028 return nfds ? nfds + 1 : 0;
1029 }
1030 /* }}} */
1031
1032 local int php_ares_extract_fds(zval *r, zval *w, fd_set *R, fd_set *W) /* {{{ */
1033 {
1034 zval **fd;
1035 int nfds = 0;
1036
1037 if (r && zend_hash_num_elements(Z_ARRVAL_P(r))) {
1038 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r));
1039 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(r), (void *) &fd);
1040 zend_hash_move_forward(Z_ARRVAL_P(r))) {
1041 if (Z_TYPE_PP(fd) == IS_LONG) {
1042 FD_SET(Z_LVAL_PP(fd), R);
1043 if (Z_LVAL_PP(fd) > nfds) {
1044 nfds = Z_LVAL_PP(fd);
1045 }
1046 }
1047 }
1048 }
1049
1050 if (w && zend_hash_num_elements(Z_ARRVAL_P(w))) {
1051 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w));
1052 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(w), (void *) &fd);
1053 zend_hash_move_forward(Z_ARRVAL_P(w))) {
1054 if (Z_TYPE_PP(fd) == IS_LONG) {
1055 FD_SET(Z_LVAL_PP(fd), W);
1056 if (Z_LVAL_PP(fd) > nfds) {
1057 nfds = Z_LVAL_PP(fd);
1058 }
1059 }
1060 }
1061 }
1062
1063 return nfds ? nfds + 1 : 0;
1064 }
1065 /* }}} */
1066
1067 static void php_ares_query_llist_dtor(void *entry)
1068 {
1069 php_ares_query *q = *(php_ares_query **) entry;
1070 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
1071 zend_list_delete(q->id);
1072 }
1073
1074 #ifdef HAVE_ARES_VERSION
1075 /* {{{ proto string ares_version()
1076 Get libares version */
1077 static PHP_FUNCTION(ares_version)
1078 {
1079 if (ZEND_NUM_ARGS()) {
1080 WRONG_PARAM_COUNT;
1081 }
1082
1083 RETURN_STRING(estrdup(ares_version(NULL)), 0);
1084 }
1085 /* }}} */
1086 #endif
1087
1088 /* {{{ proto resource ares_init([array options])
1089 Create an ares resource */
1090 static PHP_FUNCTION(ares_init)
1091 {
1092 zval *opt_array = NULL;
1093 php_ares *ares = NULL;
1094 int err;
1095
1096 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &opt_array)) {
1097 RETURN_FALSE;
1098 }
1099
1100 ares = emalloc(sizeof(php_ares));
1101 TSRMLS_SET_CTX(ares->tsrm_ls);
1102 zend_llist_init(&ares->queries, sizeof(php_ares_query *), (llist_dtor_func_t) php_ares_query_llist_dtor, 0);
1103 php_ares_options_ctor(&ares->options, opt_array ? Z_ARRVAL_P(opt_array) : NULL);
1104
1105 if (ARES_SUCCESS != (err = ares_init_options(&ares->channel, &ares->options.strct, ares->options.flags))) {
1106 php_ares_options_dtor(&ares->options);
1107 zend_llist_destroy(&ares->queries);
1108 efree(ares);
1109 RETURN_ARES_ERROR(err);
1110 }
1111
1112 ZEND_REGISTER_RESOURCE(return_value, ares, le_ares);
1113 }
1114 /* }}} */
1115
1116 #ifdef HAVE_ARES_SET_LOCAL_DEV
1117 /* {{{ proto void ares_set_local_dev(resource ares, string dev)
1118 Set the local interface name to bind to. */
1119 static PHP_FUNCTION(ares_set_local_dev)
1120 {
1121 zval *rsrc;
1122 char *dev_str = NULL;
1123 int dev_len = 0;
1124 php_ares *ares;
1125
1126 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!", &rsrc, &dev_str, &dev_len)) {
1127 RETURN_FALSE;
1128 }
1129 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1130
1131 ares_set_local_dev(ares->channel, dev_str);
1132 }
1133 #endif
1134
1135 #ifdef HAVE_ARES_SET_LOCAL_IP4
1136 /* {{{ proto void ares_set_local_ip4(resource ares, int addr)
1137 Set the local IPv4 address to bind to. */
1138 static PHP_FUNCTION(ares_set_local_ip4)
1139 {
1140 zval *rsrc;
1141 long ip4_num;
1142 php_ares *ares;
1143
1144 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &rsrc, &ip4_num)) {
1145 RETURN_FALSE;
1146 }
1147 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1148
1149 ares_set_local_ip4(ares->channel, (unsigned int) ip4_num);
1150 }
1151 #endif
1152
1153 #ifdef HAVE_ARES_SET_LOCAL_IP6
1154 /* {{{ proto void ares_set_local_ip6(resource ares, string addr128bit)
1155 Set the local IPv6 address to bind to. */
1156 static PHP_FUNCTION(ares_set_local_ip6)
1157 {
1158 zval *rsrc;
1159 char *ip6_str;
1160 int ip6_len;
1161 php_ares *ares;
1162
1163 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &ip6_str, &ip6_len)) {
1164 RETURN_FALSE;
1165 }
1166 if (16 != ip6_len) {
1167 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary IPv6 address string must be exactly 16 bytes long");
1168 }
1169 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1170
1171 ares_set_local_ip6(ares->channel, (unsigned char *) ip6_str);
1172 }
1173 #endif
1174
1175 /* {{{ proto void ares_destroy(resource ares)
1176 Destroy the ares handle */
1177 static PHP_FUNCTION(ares_destroy)
1178 {
1179 zval *rsrc;
1180 php_ares *ares;
1181
1182 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1183 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1184 if (ares->in_callback) {
1185 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy ares handle while in callback");
1186 } else {
1187 zend_list_delete(Z_LVAL_P(rsrc));
1188 }
1189 }
1190 }
1191 /* }}} */
1192
1193 /* {{{ proto string ares_strerror(int status)
1194 Get description of status code */
1195 static PHP_FUNCTION(ares_strerror)
1196 {
1197 long err;
1198 #ifdef HAVE_OLD_ARES_STRERROR
1199 char *__tmp = NULL;
1200 const char *__err;
1201 #endif
1202
1203 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &err)) {
1204 RETURN_FALSE;
1205 }
1206
1207 #ifdef HAVE_OLD_ARES_STRERROR
1208 __err = ares_strerror(err, &__tmp);
1209 RETVAL_STRING(estrdup(__err), 0);
1210 if (__tmp) {
1211 ares_free_errmem(__tmp);
1212 }
1213 #else
1214 RETURN_STRING(estrdup(ares_strerror(err)), 0);
1215 #endif
1216 }
1217 /* }}} */
1218
1219 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
1220 Compose a custom query */
1221 static PHP_FUNCTION(ares_mkquery)
1222 {
1223 char *name_str, *query_str;
1224 int name_len, query_len, err;
1225 long dnsclass, type, id, rd;
1226
1227 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &name_str, &name_len, &dnsclass, &type, &id, &rd)) {
1228 RETURN_FALSE;
1229 }
1230
1231 if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, (unsigned char **) &query_str, &query_len))) {
1232 RETURN_ARES_ERROR(err);
1233 }
1234 RETVAL_STRINGL(query_str, query_len, 1);
1235 ares_free_string(query_str);
1236 }
1237 /* }}} */
1238
1239 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1240 Issue a domain search for name */
1241 static PHP_FUNCTION(ares_search)
1242 {
1243 zval *rsrc, *cb = NULL;
1244 php_ares *ares;
1245 php_ares_query *query;
1246 char *name;
1247 int name_len;
1248 long dnsclass = C_IN, type = T_A;
1249
1250 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
1251 RETURN_FALSE;
1252 }
1253 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1254
1255 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1256 RETURN_ARES_CB_ERROR("second");
1257 }
1258
1259 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1260 php_ares_query_rsrc(query, return_value);
1261 php_ares_query_pckt(query, PHP_ARES_PCKT_SEARCH, name, name_len, type, dnsclass);
1262 ares_search(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
1263 }
1264 /* }}} */
1265
1266 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1267 Issue a single DNS query */
1268 static PHP_FUNCTION(ares_query)
1269 {
1270 zval *rsrc, *cb = NULL;
1271 php_ares *ares;
1272 php_ares_query *query;
1273 char *name;
1274 int name_len;
1275 long dnsclass = C_IN, type = T_A;
1276
1277 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
1278 RETURN_FALSE;
1279 }
1280 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1281
1282 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1283 RETURN_ARES_CB_ERROR("second");
1284 }
1285
1286 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1287 php_ares_query_rsrc(query, return_value);
1288 php_ares_query_pckt(query, PHP_ARES_PCKT_QUERY, name, name_len, type, dnsclass);
1289 ares_query(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
1290 }
1291 /* }}} */
1292
1293 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
1294 Send custom query */
1295 static PHP_FUNCTION(ares_send)
1296 {
1297 zval *rsrc, *cb = NULL;
1298 php_ares *ares;
1299 php_ares_query *query;
1300 char *buf;
1301 int len;
1302
1303 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s", &rsrc, &cb, &buf, &len)) {
1304 RETURN_FALSE;
1305 }
1306 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1307
1308 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1309 RETURN_ARES_CB_ERROR("second");
1310 }
1311
1312 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
1313 php_ares_query_rsrc(query, return_value);
1314 php_ares_query_pckt(query, PHP_ARES_PCKT_SEND, buf, len);
1315 ares_send(ares->channel, (const unsigned char *) buf, len, php_ares_callback_func, query);
1316 }
1317 /* }}} */
1318
1319 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
1320 Get host by name */
1321 static PHP_FUNCTION(ares_gethostbyname)
1322 {
1323 zval *rsrc, *cb = NULL;
1324 php_ares *ares;
1325 php_ares_query *query;
1326 char *name;
1327 int name_len;
1328 long family = AF_INET;
1329
1330 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &name, &name_len, &family)) {
1331 RETURN_FALSE;
1332 }
1333 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1334
1335 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1336 RETURN_ARES_CB_ERROR("second");
1337 }
1338
1339 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
1340 php_ares_query_rsrc(query, return_value);
1341 php_ares_query_pckt(query, PHP_ARES_PCKT_HNAME, name, name_len, family);
1342 ares_gethostbyname(ares->channel, name, family, php_ares_host_callback_func, query);
1343 }
1344 /* }}} */
1345
1346 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
1347 Get host by address */
1348 static PHP_FUNCTION(ares_gethostbyaddr)
1349 {
1350 zval *rsrc, *cb = NULL;
1351 php_ares *ares;
1352 php_ares_query *query;
1353 char *addr;
1354 int addr_len;
1355 long family = AF_INET;
1356 void *sa;
1357 int sa_len;
1358
1359 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &addr, &addr_len, &family)) {
1360 RETURN_FALSE;
1361 }
1362 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1363
1364 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1365 PHP_ARES_CB_ERROR("second");
1366 RETURN_FALSE;
1367 }
1368
1369 switch (family) {
1370 case AF_INET:
1371 sa = emalloc(sa_len = sizeof(struct in_addr));
1372 break;
1373 case AF_INET6:
1374 sa = emalloc(sa_len = sizeof(struct in6_addr));
1375 break;
1376 default:
1377 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1378 RETURN_FALSE;
1379 break;
1380 }
1381
1382 if (1 > inet_pton(family, addr, sa)) {
1383 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1384 RETVAL_FALSE;
1385 } else {
1386 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
1387 php_ares_query_rsrc(query, return_value);
1388 php_ares_query_pckt(query, PHP_ARES_PCKT_HADDR, addr, addr_len, family);
1389 ares_gethostbyaddr(ares->channel, sa, sa_len, family, php_ares_host_callback_func, query);
1390 }
1391 efree(sa);
1392 }
1393 /* }}} */
1394
1395 #ifdef HAVE_ARES_GETNAMEINFO
1396 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1397 Get name info */
1398 static PHP_FUNCTION(ares_getnameinfo)
1399 {
1400 zval *rsrc, *cb = NULL;
1401 php_ares *ares;
1402 php_ares_query *query;
1403 char *addr;
1404 int addr_len;
1405 long flags, port = 0, family = AF_INET;
1406 struct sockaddr *sa;
1407 struct sockaddr_in *in;
1408 struct sockaddr_in6 *in6;
1409 int sa_len;
1410
1411 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!ls|ll", &rsrc, &cb, &flags, &addr, &addr_len, &family, &port)) {
1412 RETURN_FALSE;
1413 }
1414 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1415
1416 if (cb && !PHP_ARES_IS_CALLABLE(cb, 0, NULL)) {
1417 PHP_ARES_CB_ERROR("second");
1418 RETURN_FALSE;
1419 }
1420
1421 RETVAL_TRUE;
1422 switch (family) {
1423 case AF_INET:
1424 in = ecalloc(1, sa_len = sizeof(struct sockaddr_in));
1425 in->sin_family = AF_INET;
1426 in->sin_port = htons((unsigned short) port);
1427 if (1 > inet_pton(in->sin_family, addr, &in->sin_addr)) {
1428 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1429 RETVAL_FALSE;
1430 }
1431 sa = (struct sockaddr *) in;
1432 break;
1433 case AF_INET6:
1434 in6 = ecalloc(1, sa_len = sizeof(struct sockaddr_in6));
1435 in6->sin6_family = AF_INET6;
1436 in6->sin6_port = htons((unsigned short) port);
1437 if (1 > inet_pton(in6->sin6_family, addr, &in6->sin6_addr)) {
1438 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1439 RETVAL_FALSE;
1440 }
1441 sa = (struct sockaddr *) in6;
1442 break;
1443 default:
1444 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither AF_INET nor AF_INET6");
1445 RETURN_FALSE;
1446 break;
1447 }
1448
1449 if (Z_BVAL_P(return_value)) {
1450 query = php_ares_query_ctor(NULL, PHP_ARES_CB_NINFO, ares, cb);
1451 php_ares_query_rsrc(query, return_value);
1452 php_ares_query_pckt(query, PHP_ARES_PCKT_NINFO, flags, addr, addr_len, family, port);
1453 ares_getnameinfo(ares->channel, sa, sa_len, flags, php_ares_nameinfo_callback_func, query);
1454 }
1455 efree(sa);
1456 }
1457 /* }}} */
1458 #endif
1459
1460 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1461 Check a query for its result */
1462 static PHP_FUNCTION(ares_result)
1463 {
1464 zval *rsrc, *zerrno = NULL, *zerror = NULL;
1465 php_ares_query *query;
1466
1467 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|zz", &rsrc, &zerrno, &zerror)) {
1468 RETURN_FALSE;
1469 }
1470 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1471
1472 if (zerrno) {
1473 zval_dtor(zerrno);
1474 ZVAL_LONG(zerrno, query->error);
1475 }
1476 if (zerror) {
1477 zval_dtor(zerror);
1478 ZVAL_NULL(zerror);
1479 }
1480
1481 switch (query->error) {
1482 case 0:
1483 switch (query->type) {
1484 case PHP_ARES_CB_STD:
1485 if (query->result.std.arr) {
1486 RETVAL_ZVAL(query->result.std.arr, 1, 0);
1487 } else {
1488 RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
1489 }
1490 break;
1491 case PHP_ARES_CB_HOST:
1492 object_init(return_value);
1493 php_ares_hostent_to_struct(&query->result.host, HASH_OF(return_value));
1494 break;
1495 case PHP_ARES_CB_NINFO:
1496 object_init(return_value);
1497 add_property_string(return_value, "node", query->result.ninfo.node ? query->result.ninfo.node : "", 1);
1498 add_property_string(return_value, "service", query->result.ninfo.service ? query->result.ninfo.service : "", 1);
1499 break;
1500 }
1501 break;
1502 case -1:
1503 RETVAL_FALSE;
1504 break;
1505 default:
1506 if (zerror) {
1507 #ifdef HAVE_OLD_ARES_STRERROR
1508 char *__tmp = NULL;
1509 const char *__err = ares_strerror(query->error, &__tmp);
1510 ZVAL_STRING(zerror, estrdup(__err), 0);
1511 if (__tmp) ares_free_errmem(__tmp);
1512 #else
1513 ZVAL_STRING(zerror, estrdup(ares_strerror(query->error)), 0);
1514 #endif
1515 }
1516 RETVAL_FALSE;
1517 break;
1518 }
1519 }
1520 /* }}} */
1521
1522 /* {{{ proto object ares_packet(resource query)
1523 Check a query for its question packet */
1524 static PHP_FUNCTION(ares_packet)
1525 {
1526 zval *rsrc, *prop;
1527 php_ares_query *query;
1528
1529 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1530 RETURN_FALSE;
1531 }
1532 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1533
1534 object_init(return_value);
1535 add_property_long(return_value, "type", query->packet.type);
1536 add_property_null(return_value, "search");
1537 add_property_null(return_value, "query");
1538 add_property_null(return_value, "send");
1539 add_property_null(return_value, "gethostbyname");
1540 add_property_null(return_value, "gethostbyaddr");
1541 add_property_null(return_value, "getnameinfo");
1542 MAKE_STD_ZVAL(prop);
1543
1544 switch (query->packet.type) {
1545 case PHP_ARES_PCKT_SEARCH:
1546 object_init(prop);
1547 add_property_stringl(prop, "name", query->packet.data.search.name, query->packet.data.search.name_len, 1);
1548 add_property_long(prop, "type", query->packet.data.search.type);
1549 add_property_long(prop, "dnsclass", query->packet.data.search.dnsclass);
1550 add_property_zval(return_value, "search", prop);
1551 break;
1552
1553 case PHP_ARES_PCKT_QUERY:
1554 object_init(prop);
1555 add_property_stringl(prop, "name", query->packet.data.query.name, query->packet.data.query.name_len, 1);
1556 add_property_long(prop, "type", query->packet.data.query.type);
1557 add_property_long(prop, "dnsclass", query->packet.data.query.dnsclass);
1558 add_property_zval(return_value, "query", prop);
1559 break;
1560
1561 case PHP_ARES_PCKT_SEND:
1562 ZVAL_STRINGL(prop, query->packet.data.send.buf, query->packet.data.send.len, 1);
1563 add_property_zval(return_value, "send", prop);
1564 break;
1565
1566 case PHP_ARES_PCKT_HNAME:
1567 object_init(prop);
1568 add_property_stringl(prop, "name", query->packet.data.hname.name, query->packet.data.hname.name_len, 1);
1569 add_property_long(prop, "family", query->packet.data.hname.family);
1570 add_property_zval(return_value, "gethostbyname", prop);
1571 break;
1572
1573 case PHP_ARES_PCKT_HADDR:
1574 object_init(prop);
1575 add_property_stringl(prop, "addr", query->packet.data.haddr.addr, query->packet.data.haddr.addr_len, 1);
1576 add_property_long(prop, "family", query->packet.data.haddr.family);
1577 add_property_zval(return_value, "gethostbyaddr", prop);
1578 break;
1579
1580 case PHP_ARES_PCKT_NINFO:
1581 object_init(prop);
1582 add_property_long(prop, "flags", query->packet.data.ninfo.flags);
1583 add_property_stringl(prop, "addr", query->packet.data.ninfo.addr, query->packet.data.ninfo.addr_len, 1);
1584 add_property_long(prop, "family", query->packet.data.ninfo.family);
1585 add_property_long(prop, "port", query->packet.data.ninfo.port);
1586 add_property_zval(return_value, "getnameinfo", prop);
1587 break;
1588 }
1589
1590 zval_ptr_dtor(&prop);
1591 }
1592 /* }}} */
1593
1594 #ifdef HAVE_ARES_CANCEL
1595 /* {{{ proto void ares_cancel(resource ares)
1596 Cancel pending queries */
1597 static PHP_FUNCTION(ares_cancel)
1598 {
1599 zval *rsrc;
1600 php_ares *ares;
1601
1602 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1603 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1604 ares_cancel(ares->channel);
1605 }
1606 }
1607 /* }}} */
1608 #endif
1609
1610 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1611 Process all pending queries */
1612 static PHP_FUNCTION(ares_process_all)
1613 {
1614 zval *rsrc;
1615 php_ares *ares;
1616 long max_timeout = -1;
1617
1618 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1619 RETURN_FALSE;
1620 }
1621 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1622
1623 while (php_ares_process(ares, max_timeout));
1624 }
1625 /* }}} */
1626
1627 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1628 Process once and return whether it should be called again */
1629 static PHP_FUNCTION(ares_process_once)
1630 {
1631 zval *rsrc;
1632 php_ares *ares;
1633 long max_timeout = -1;
1634
1635 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1636 RETURN_FALSE;
1637 }
1638 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1639
1640 RETVAL_BOOL(php_ares_process(ares, max_timeout));
1641 }
1642 /* }}} */
1643
1644 /* {{{ proto void ares_process(resource ares, array read, array write)
1645 Process call */
1646 static PHP_FUNCTION(ares_process)
1647 {
1648 zval *rsrc, *read = NULL, *write = NULL;
1649 fd_set R, W;
1650 php_ares *ares;
1651
1652 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a!a!", &rsrc, &read, &write)) {
1653 RETURN_FALSE;
1654 }
1655 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1656
1657 FD_ZERO(&R);
1658 FD_ZERO(&W);
1659
1660 php_ares_extract_fds(read, write, &R, &W);
1661 ares_process(ares->channel, &R, &W);
1662 }
1663 /* }}} */
1664
1665 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1666 Select call */
1667 static PHP_FUNCTION(ares_select)
1668 {
1669 zval *read = NULL, *write = NULL;
1670 fd_set R, W;
1671 int nfds;
1672 long timeout;
1673 struct timeval tv;
1674
1675 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aal", &read, &write, &timeout)) {
1676 RETURN_FALSE;
1677 }
1678
1679 if (timeout) {
1680 tv.tv_sec = timeout / 1000;
1681 tv.tv_usec = timeout % (timeout * 1000);
1682 } else {
1683 tv.tv_sec = 1;
1684 tv.tv_usec = 0;
1685 }
1686
1687 FD_ZERO(&R);
1688 FD_ZERO(&W);
1689
1690 nfds = php_ares_extract_fds(read, write, &R, &W);
1691 if (-1 < select(nfds, &R, &W, NULL, &tv)) {
1692 zend_hash_clean(Z_ARRVAL_P(read));
1693 zend_hash_clean(Z_ARRVAL_P(write));
1694 php_ares_publish_fds(&R, &W, read, write);
1695 RETURN_TRUE;
1696 }
1697 RETURN_FALSE;
1698 }
1699 /* }}} */
1700
1701 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1702 Get suggested select timeout in ms */
1703 static PHP_FUNCTION(ares_timeout)
1704 {
1705 zval *rsrc;
1706 long max_timeout = -1;
1707 struct timeval tv, *tvptr;
1708 php_ares *ares;
1709
1710 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1711 RETURN_FALSE;
1712 }
1713 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1714
1715 if ((tvptr = php_ares_timeout(ares, max_timeout, &tv))) {
1716 RETURN_LONG(tvptr->tv_sec * 1000 + tvptr->tv_usec / 1000);
1717 }
1718 RETURN_LONG(0);
1719 }
1720 /* }}} */
1721
1722 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1723 Get file descriptors */
1724 static PHP_FUNCTION(ares_fds)
1725 {
1726 zval *rsrc, *read, *write;
1727 fd_set R, W;
1728 php_ares *ares;
1729
1730 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzz", &rsrc, &read, &write)) {
1731 RETURN_FALSE;
1732 }
1733 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1734
1735 FD_ZERO(&R);
1736 FD_ZERO(&W);
1737
1738 zval_dtor(read);
1739 zval_dtor(write);
1740 array_init(read);
1741 array_init(write);
1742 ares_fds(ares->channel, &R, &W);
1743 RETVAL_LONG(php_ares_publish_fds(&R, &W, read, write));
1744 }
1745 /* }}} */
1746
1747 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor)
1748 {
1749 php_ares *ares = (php_ares *) rsrc->ptr;
1750
1751 ares_destroy(ares->channel);
1752 zend_llist_destroy(&ares->queries);
1753 php_ares_options_dtor(&ares->options);
1754 efree(ares);
1755 }
1756
1757 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor)
1758 {
1759 php_ares_query *query = (php_ares_query *) rsrc->ptr;
1760
1761 php_ares_query_dtor(query);
1762 efree(query);
1763 }
1764
1765 /* {{{ PHP_MINIT_FUNCTION */
1766 static PHP_MINIT_FUNCTION(ares)
1767 {
1768 #ifdef HAVE_ARES_LIBRARY_INIT
1769 if (ARES_SUCCESS != ares_library_init(ARES_LIB_INIT_ALL)) {
1770 return FAILURE;
1771 }
1772 #endif
1773 #ifdef HAVE_ARES_VERSION
1774 {
1775 int ares_version_num;
1776 ares_version(&ares_version_num);
1777
1778 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
1779 }
1780 #endif
1781
1782 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS, CONST_PERSISTENT|CONST_CS);
1783 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA, CONST_PERSISTENT|CONST_CS);
1784 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR, CONST_PERSISTENT|CONST_CS);
1785 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL, CONST_PERSISTENT|CONST_CS);
1786 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND, CONST_PERSISTENT|CONST_CS);
1787 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP, CONST_PERSISTENT|CONST_CS);
1788 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED, CONST_PERSISTENT|CONST_CS);
1789 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY, CONST_PERSISTENT|CONST_CS);
1790 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME, CONST_PERSISTENT|CONST_CS);
1791 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY, CONST_PERSISTENT|CONST_CS);
1792 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP, CONST_PERSISTENT|CONST_CS);
1793 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED, CONST_PERSISTENT|CONST_CS);
1794 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT, CONST_PERSISTENT|CONST_CS);
1795 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF, CONST_PERSISTENT|CONST_CS);
1796 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE, CONST_PERSISTENT|CONST_CS);
1797 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM, CONST_PERSISTENT|CONST_CS);
1798 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION, CONST_PERSISTENT|CONST_CS);
1799 #ifdef ARES_EBADSTR
1800 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR, CONST_PERSISTENT|CONST_CS);
1801 #endif
1802 #ifdef ARES_EBADFLAGS
1803 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS, CONST_PERSISTENT|CONST_CS);
1804 #endif
1805 #ifdef ARES_ENONAME
1806 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME, CONST_PERSISTENT|CONST_CS);
1807 #endif
1808 #ifdef ARES_EBADHINTS
1809 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS, CONST_PERSISTENT|CONST_CS);
1810 #endif
1811 #ifdef ARES_ENOTINITIALIZED
1812 REGISTER_LONG_CONSTANT("ARES_ENOTINITIALIZED", ARES_ENOTINITIALIZED, CONST_PERSISTENT|CONST_CS);
1813 #endif
1814 #ifdef ARES_ELOADIPHLPAPI
1815 REGISTER_LONG_CONSTANT("ARES_ELOADIPHLPAPI", ARES_ELOADIPHLPAPI, CONST_PERSISTENT|CONST_CS);
1816 #endif
1817 #ifdef ARES_EADDRGETNETWORKPARAMS
1818 REGISTER_LONG_CONSTANT("ARES_EADDRGETNETWORKPARAMS", ARES_EADDRGETNETWORKPARAMS, CONST_PERSISTENT|CONST_CS);
1819 #endif
1820 #ifdef ARES_ECANCELLED
1821 REGISTER_LONG_CONSTANT("ARES_ECANCELLED", ARES_ECANCELLED, CONST_PERSISTENT|CONST_CS);
1822 #endif
1823
1824 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC, CONST_PERSISTENT|CONST_CS);
1825 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY, CONST_PERSISTENT|CONST_CS);
1826 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC, CONST_PERSISTENT|CONST_CS);
1827 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE, CONST_PERSISTENT|CONST_CS);
1828 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN, CONST_PERSISTENT|CONST_CS);
1829 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH, CONST_PERSISTENT|CONST_CS);
1830 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES, CONST_PERSISTENT|CONST_CS);
1831 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP, CONST_PERSISTENT|CONST_CS);
1832 #ifdef ARES_FLAG_EDNS
1833 REGISTER_LONG_CONSTANT("ARES_FLAG_EDNS", ARES_FLAG_EDNS, CONST_PERSISTENT|CONST_CS);
1834 #endif
1835
1836 /*
1837 * Address Family Constants
1838 */
1839 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET, CONST_PERSISTENT|CONST_CS);
1840 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6, CONST_PERSISTENT|CONST_CS);
1841
1842 /*
1843 * Name Info constants
1844 */
1845 #ifdef ARES_NI_NOFQDN
1846 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN, CONST_PERSISTENT|CONST_CS);
1847 #endif
1848 #ifdef ARES_NI_NUMERICHOST
1849 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1850 #endif
1851 #ifdef ARES_NI_NAMEREQD
1852 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD, CONST_PERSISTENT|CONST_CS);
1853 #endif
1854 #ifdef ARES_NI_NUMERICSERV
1855 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1856 #endif
1857 #ifdef ARES_NI_DGRAM
1858 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM, CONST_PERSISTENT|CONST_CS);
1859 #endif
1860 #ifdef ARES_NI_TCP
1861 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP, CONST_PERSISTENT|CONST_CS);
1862 #endif
1863 #ifdef ARES_NI_UDP
1864 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP, CONST_PERSISTENT|CONST_CS);
1865 #endif
1866 #ifdef ARES_NI_SCTP
1867 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP, CONST_PERSISTENT|CONST_CS);
1868 #endif
1869 #ifdef ARES_NI_DCCP
1870 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP, CONST_PERSISTENT|CONST_CS);
1871 #endif
1872 #ifdef ARES_NI_NUMERICSCOPE
1873 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE, CONST_PERSISTENT|CONST_CS);
1874 #endif
1875 #ifdef ARES_NI_LOOKUPHOST
1876 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST, CONST_PERSISTENT|CONST_CS);
1877 #endif
1878 #ifdef ARES_NI_LOOKUPSERVICE
1879 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE, CONST_PERSISTENT|CONST_CS);
1880 #endif
1881 #ifdef ARES_NI_IDN
1882 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN, CONST_PERSISTENT|CONST_CS);
1883 #endif
1884 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1885 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1886 #endif
1887 #ifdef ARES_NI_IDN_USE_STD
1888 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1889 #endif
1890
1891 /*
1892 * Address Info constants
1893 */
1894 #ifdef ARES_AI_CANONNAME
1895 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME, CONST_PERSISTENT|CONST_CS);
1896 #endif
1897 #ifdef ARES_AI_NUMERICHOST
1898 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1899 #endif
1900 #ifdef ARES_AI_PASSIVE
1901 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE, CONST_PERSISTENT|CONST_CS);
1902 #endif
1903 #ifdef ARES_AI_NUMERICSERV
1904 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1905 #endif
1906 #ifdef ARES_AI_V
1907 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V, CONST_PERSISTENT|CONST_CS);
1908 #endif
1909 #ifdef ARES_AI_ALL
1910 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL, CONST_PERSISTENT|CONST_CS);
1911 #endif
1912 #ifdef ARES_AI_ADDRCONFIG
1913 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG, CONST_PERSISTENT|CONST_CS);
1914 #endif
1915 #ifdef ARES_AI_IDN
1916 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN, CONST_PERSISTENT|CONST_CS);
1917 #endif
1918 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1919 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1920 #endif
1921 #ifdef ARES_AI_IDN_USE_STD
1922 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1923 #endif
1924 #ifdef ARES_AI_CANONIDN
1925 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN, CONST_PERSISTENT|CONST_CS);
1926 #endif
1927 #ifdef ARES_AI_MASK
1928 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK, CONST_PERSISTENT|CONST_CS);
1929 #endif
1930 #ifdef ARES_GETSOCK_MAXNUM
1931 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM, CONST_PERSISTENT|CONST_CS);
1932 #endif
1933
1934 /*
1935 * ns_t (type) constants (arpa/nameser.h)
1936 */
1937 #ifdef T_A
1938 /* (1) Host address. */
1939 REGISTER_LONG_CONSTANT("ARES_T_A", T_A, CONST_CS|CONST_PERSISTENT);
1940 #endif
1941 #ifdef T_NS
1942 /* (2) Authoritative server. */
1943 REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS, CONST_CS|CONST_PERSISTENT);
1944 #endif
1945 #ifdef T_MD
1946 /* (3) Mail destination. */
1947 REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD, CONST_CS|CONST_PERSISTENT);
1948 #endif
1949 #ifdef T_MF
1950 /* (4) Mail forwarder. */
1951 REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF, CONST_CS|CONST_PERSISTENT);
1952 #endif
1953 #ifdef T_CNAME
1954 /* (5) Canonical name. */
1955 REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME, CONST_CS|CONST_PERSISTENT);
1956 #endif
1957 #ifdef T_SOA
1958 /* (6) Start of authority zone. */
1959 REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA, CONST_CS|CONST_PERSISTENT);
1960 #endif
1961 #ifdef T_MB
1962 /* (7) Mailbox domain name. */
1963 REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB, CONST_CS|CONST_PERSISTENT);
1964 #endif
1965 #ifdef T_MG
1966 /* (8) Mail group member. */
1967 REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG, CONST_CS|CONST_PERSISTENT);
1968 #endif
1969 #ifdef T_MR
1970 /* (9) Mail rename name. */
1971 REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR, CONST_CS|CONST_PERSISTENT);
1972 #endif
1973 #ifdef T_NULL
1974 /* (10) Null resource record. */
1975 REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL, CONST_CS|CONST_PERSISTENT);
1976 #endif
1977 #ifdef T_WKS
1978 /* (11) Well known service. */
1979 REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS, CONST_CS|CONST_PERSISTENT);
1980 #endif
1981 #ifdef T_PTR
1982 /* (12) Domain name pointer. */
1983 REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR, CONST_CS|CONST_PERSISTENT);
1984 #endif
1985 #ifdef T_HINFO
1986 /* (13) Host information. */
1987 REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO, CONST_CS|CONST_PERSISTENT);
1988 #endif
1989 #ifdef T_MINFO
1990 /* (14) Mailbox information. */
1991 REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO, CONST_CS|CONST_PERSISTENT);
1992 #endif
1993 #ifdef T_MX
1994 /* (15) Mail routing information. */
1995 REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX, CONST_CS|CONST_PERSISTENT);
1996 #endif
1997 #ifdef T_TXT
1998 /* (16) Text strings. */
1999 REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT, CONST_CS|CONST_PERSISTENT);
2000 #endif
2001 #ifdef T_RP
2002 /* (17) Responsible person. */
2003 REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP, CONST_CS|CONST_PERSISTENT);
2004 #endif
2005 #ifdef T_AFSDB
2006 /* (18) AFS cell database. */
2007 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB, CONST_CS|CONST_PERSISTENT);
2008 #endif
2009 #ifdef T_X25
2010 /* (19) X_25 calling address. */
2011 REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25, CONST_CS|CONST_PERSISTENT);
2012 #endif
2013 #ifdef T_ISDN
2014 /* (20) ISDN calling address. */
2015 REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN, CONST_CS|CONST_PERSISTENT);
2016 #endif
2017 #ifdef T_RT
2018 /* (21) Router. */
2019 REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT, CONST_CS|CONST_PERSISTENT);
2020 #endif
2021 #ifdef T_NSAP
2022 /* (22) NSAP address. */
2023 REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP, CONST_CS|CONST_PERSISTENT);
2024 #endif
2025 #ifdef T_NSAP_PTR
2026 /* (23) Reverse NSAP lookup (deprecated). */
2027 REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR, CONST_CS|CONST_PERSISTENT);
2028 #endif
2029 #ifdef T_SIG
2030 /* (24) Security signature. */
2031 REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG, CONST_CS|CONST_PERSISTENT);
2032 #endif
2033 #ifdef T_KEY
2034 /* (25) Security key. */
2035 REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY, CONST_CS|CONST_PERSISTENT);
2036 #endif
2037 #ifdef T_PX
2038 /* (26) X.400 mail mapping. */
2039 REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX, CONST_CS|CONST_PERSISTENT);
2040 #endif
2041 #ifdef T_GPOS
2042 /* (27) Geographical position (withdrawn). */
2043 REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS, CONST_CS|CONST_PERSISTENT);
2044 #endif
2045 #ifdef T_AAAA
2046 /* (28) Ip6 Address. */
2047 REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA, CONST_CS|CONST_PERSISTENT);
2048 #endif
2049 #ifdef T_LOC
2050 /* (29) Location Information. */
2051 REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC, CONST_CS|CONST_PERSISTENT);
2052 #endif
2053 #ifdef T_NXT
2054 /* (30) Next domain (security). */
2055 REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT, CONST_CS|CONST_PERSISTENT);
2056 #endif
2057 #ifdef T_EID
2058 /* (31) Endpoint identifier. */
2059 REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID, CONST_CS|CONST_PERSISTENT);
2060 #endif
2061 #ifdef T_NIMLOC
2062 /* (32) Nimrod Locator. */
2063 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC, CONST_CS|CONST_PERSISTENT);
2064 #endif
2065 #ifdef T_SRV
2066 /* (33) Server Selection. */
2067 REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV, CONST_CS|CONST_PERSISTENT);
2068 #endif
2069 #ifdef T_ATMA
2070 /* (34) ATM Address */
2071 REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA, CONST_CS|CONST_PERSISTENT);
2072 #endif
2073 #ifdef T_NAPTR
2074 /* (35) Naming Authority Pointer */
2075 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR, CONST_CS|CONST_PERSISTENT);
2076 #endif
2077 #ifdef T_KX
2078 /* (36) Key Exchange */
2079 REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX, CONST_CS|CONST_PERSISTENT);
2080 #endif
2081 #ifdef T_CERT
2082 /* (37) Certification record */
2083 REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT, CONST_CS|CONST_PERSISTENT);
2084 #endif
2085 #ifdef T_A6
2086 /* (38) IPv6 address (deprecates AAAA) */
2087 REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6, CONST_CS|CONST_PERSISTENT);
2088 #endif
2089 #ifdef T_DNAME
2090 /* (39) Non-terminal DNAME (for IPv6) */
2091 REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME, CONST_CS|CONST_PERSISTENT);
2092 #endif
2093 #ifdef T_SINK
2094 /* (40) Kitchen sink (experimentatl) */
2095 REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK, CONST_CS|CONST_PERSISTENT);
2096 #endif
2097 #ifdef T_OPT
2098 /* (41) EDNS0 option (meta-RR) */
2099 REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT, CONST_CS|CONST_PERSISTENT);
2100 #endif
2101 #ifdef T_TSIG
2102 /* (250) Transaction signature. */
2103 REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG, CONST_CS|CONST_PERSISTENT);
2104 #endif
2105 #ifdef T_IXFR
2106 /* (251) Incremental zone transfer. */
2107 REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR, CONST_CS|CONST_PERSISTENT);
2108 #endif
2109 #ifdef T_AXFR
2110 /* (252) Transfer zone of authority. */
2111 REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR, CONST_CS|CONST_PERSISTENT);
2112 #endif
2113 #ifdef T_MAILB
2114 /* (253) Transfer mailbox records. */
2115 REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB, CONST_CS|CONST_PERSISTENT);
2116 #endif
2117 #ifdef T_MAILA
2118 /* (254) Transfer mail agent records. */
2119 REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA, CONST_CS|CONST_PERSISTENT);
2120 #endif
2121 #ifdef T_ANY
2122 /* (255) Wildcard match. */
2123 REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY, CONST_CS|CONST_PERSISTENT);
2124 #endif
2125
2126 /*
2127 * ns_c (dnsclass) constants (arpa/nameser.h)
2128 */
2129
2130 #ifdef C_IN
2131 /* (1) Internet. */
2132 REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN, CONST_CS|CONST_PERSISTENT);
2133 #endif
2134 #ifdef C_2
2135 /* (2) unallocated/unsupported. */
2136 REGISTER_LONG_CONSTANT("ARES_C_2", C_2, CONST_CS|CONST_PERSISTENT);
2137 #endif
2138 #ifdef C_CHAOS
2139 /* (3) MIT Chaos-net. */
2140 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS, CONST_CS|CONST_PERSISTENT);
2141 #endif
2142 #ifdef C_HS
2143 /* (4) MIT Hesiod. */
2144 REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS, CONST_CS|CONST_PERSISTENT);
2145 #endif
2146 #ifdef C_NONE
2147 /* (254) for prereq. sections in update requests */
2148 REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE, CONST_CS|CONST_PERSISTENT);
2149 #endif
2150 #ifdef C_ANY
2151 /* (255) Wildcard match. */
2152 REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY, CONST_CS|CONST_PERSISTENT);
2153 #endif
2154
2155 le_ares = zend_register_list_destructors_ex(php_ares_le_dtor, NULL, PHP_ARES_LE_NAME, module_number);
2156 le_ares_query = zend_register_list_destructors_ex(php_ares_query_le_dtor, NULL, PHP_ARES_QUERY_LE_NAME, module_number);
2157
2158 return SUCCESS;
2159 }
2160 /* }}} */
2161
2162 /* {{{ PHP_MSHUTDOWN_FUNCTION */
2163 static PHP_MSHUTDOWN_FUNCTION(ares)
2164 {
2165 #ifdef HAVE_ARES_LIBRARY_CLEANUP
2166 ares_library_cleanup();
2167 #endif
2168 return SUCCESS;
2169 }
2170 /* }}} */
2171
2172 /* {{{ PHP_MINFO_FUNCTION */
2173 static PHP_MINFO_FUNCTION(ares)
2174 {
2175 php_info_print_table_start();
2176 php_info_print_table_header(2, "AsyncResolver support", "enabled");
2177 php_info_print_table_row(2, "Version", PHP_ARES_VERSION);
2178 php_info_print_table_end();
2179
2180 php_info_print_table_start();
2181 php_info_print_table_header(3, "Used Library", "compiled", "linked");
2182 php_info_print_table_row(3,
2183 PHP_ARES_LIBNAME,
2184 #ifdef ARES_VERSION_STR
2185 ARES_VERSION_STR,
2186 #else
2187 "unkown",
2188 #endif
2189 #ifdef HAVE_ARES_VERSION
2190 ares_version(NULL)
2191 #else
2192 "unkown"
2193 #endif
2194 );
2195 php_info_print_table_end();
2196 }
2197 /* }}} */
2198
2199 #ifdef ZEND_ENGINE_2
2200 ZEND_BEGIN_ARG_INFO(ai_ares_select, 0)
2201 ZEND_ARG_PASS_INFO(1)
2202 ZEND_ARG_PASS_INFO(1)
2203 ZEND_ARG_PASS_INFO(0)
2204 ZEND_END_ARG_INFO();
2205
2206 ZEND_BEGIN_ARG_INFO(ai_ares_result, 0)
2207 ZEND_ARG_PASS_INFO(0)
2208 ZEND_ARG_PASS_INFO(1)
2209 ZEND_ARG_PASS_INFO(1)
2210 ZEND_END_ARG_INFO();
2211
2212 ZEND_BEGIN_ARG_INFO(ai_ares_fds, 0)
2213 ZEND_ARG_PASS_INFO(0)
2214 ZEND_ARG_PASS_INFO(1)
2215 ZEND_ARG_PASS_INFO(1)
2216 ZEND_END_ARG_INFO();
2217 #else
2218 static unsigned char ai_ares_select[] = {3, BYREF_FORCE, BYREF_FORCE, BYREF_NONE};
2219 static unsigned char ai_ares_result[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2220 static unsigned char ai_ares_fds[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2221 #endif
2222
2223 /* {{{ ares_functions[] */
2224 zend_function_entry ares_functions[] = {
2225 #ifdef HAVE_ARES_VERSION
2226 PHP_FE(ares_version, NULL)
2227 #endif
2228 PHP_FE(ares_init, NULL)
2229 PHP_FE(ares_destroy, NULL)
2230 PHP_FE(ares_strerror, NULL)
2231 #ifdef HAVE_ARES_CANCEL
2232 PHP_FE(ares_cancel, NULL)
2233 #endif
2234 PHP_FE(ares_search, NULL)
2235 PHP_FE(ares_query, NULL)
2236 PHP_FE(ares_send, NULL)
2237 PHP_FE(ares_mkquery, NULL)
2238 PHP_FE(ares_gethostbyname, NULL)
2239 PHP_FE(ares_gethostbyaddr, NULL)
2240 #ifdef HAVE_ARES_GETNAMEINFO
2241 PHP_FE(ares_getnameinfo, NULL)
2242 #endif
2243 PHP_FE(ares_result, ai_ares_result)
2244 PHP_FE(ares_packet, NULL)
2245 PHP_FE(ares_process_all, NULL)
2246 PHP_FE(ares_process_once, NULL)
2247 PHP_FE(ares_process, NULL)
2248 PHP_FE(ares_select, ai_ares_select)
2249 PHP_FE(ares_fds, ai_ares_fds)
2250 PHP_FE(ares_timeout, NULL)
2251 {NULL, NULL, NULL}
2252 };
2253 /* }}} */
2254
2255 /* {{{ ares_module_entry */
2256 zend_module_entry ares_module_entry = {
2257 STANDARD_MODULE_HEADER,
2258 "ares",
2259 ares_functions,
2260 PHP_MINIT(ares),
2261 PHP_MSHUTDOWN(ares),
2262 NULL,
2263 NULL,
2264 PHP_MINFO(ares),
2265 PHP_ARES_VERSION,
2266 STANDARD_MODULE_PROPERTIES
2267 };
2268 /* }}} */
2269
2270 #ifdef COMPILE_DL_ARES
2271 ZEND_GET_MODULE(ares)
2272 #endif
2273
2274 /*
2275 * Local variables:
2276 * tab-width: 4
2277 * c-basic-offset: 4
2278 * End:
2279 * vim600: noet sw=4 ts=4 fdm=marker
2280 * vim<600: noet sw=4 ts=4
2281 */