680c4d9c8cf9cead446a1bb4155f7e7fc8679e48
[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 = htons((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 = htons((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
1833 /*
1834 * Address Family Constants
1835 */
1836 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET, CONST_PERSISTENT|CONST_CS);
1837 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6, CONST_PERSISTENT|CONST_CS);
1838
1839 /*
1840 * Name Info constants
1841 */
1842 #ifdef ARES_NI_NOFQDN
1843 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN, CONST_PERSISTENT|CONST_CS);
1844 #endif
1845 #ifdef ARES_NI_NUMERICHOST
1846 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1847 #endif
1848 #ifdef ARES_NI_NAMEREQD
1849 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD, CONST_PERSISTENT|CONST_CS);
1850 #endif
1851 #ifdef ARES_NI_NUMERICSERV
1852 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1853 #endif
1854 #ifdef ARES_NI_DGRAM
1855 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM, CONST_PERSISTENT|CONST_CS);
1856 #endif
1857 #ifdef ARES_NI_TCP
1858 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP, CONST_PERSISTENT|CONST_CS);
1859 #endif
1860 #ifdef ARES_NI_UDP
1861 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP, CONST_PERSISTENT|CONST_CS);
1862 #endif
1863 #ifdef ARES_NI_SCTP
1864 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP, CONST_PERSISTENT|CONST_CS);
1865 #endif
1866 #ifdef ARES_NI_DCCP
1867 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP, CONST_PERSISTENT|CONST_CS);
1868 #endif
1869 #ifdef ARES_NI_NUMERICSCOPE
1870 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE, CONST_PERSISTENT|CONST_CS);
1871 #endif
1872 #ifdef ARES_NI_LOOKUPHOST
1873 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST, CONST_PERSISTENT|CONST_CS);
1874 #endif
1875 #ifdef ARES_NI_LOOKUPSERVICE
1876 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE, CONST_PERSISTENT|CONST_CS);
1877 #endif
1878 #ifdef ARES_NI_IDN
1879 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN, CONST_PERSISTENT|CONST_CS);
1880 #endif
1881 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1882 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1883 #endif
1884 #ifdef ARES_NI_IDN_USE_STD
1885 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1886 #endif
1887
1888 /*
1889 * Address Info constants
1890 */
1891 #ifdef ARES_AI_CANONNAME
1892 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME, CONST_PERSISTENT|CONST_CS);
1893 #endif
1894 #ifdef ARES_AI_NUMERICHOST
1895 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1896 #endif
1897 #ifdef ARES_AI_PASSIVE
1898 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE, CONST_PERSISTENT|CONST_CS);
1899 #endif
1900 #ifdef ARES_AI_NUMERICSERV
1901 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1902 #endif
1903 #ifdef ARES_AI_V
1904 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V, CONST_PERSISTENT|CONST_CS);
1905 #endif
1906 #ifdef ARES_AI_ALL
1907 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL, CONST_PERSISTENT|CONST_CS);
1908 #endif
1909 #ifdef ARES_AI_ADDRCONFIG
1910 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG, CONST_PERSISTENT|CONST_CS);
1911 #endif
1912 #ifdef ARES_AI_IDN
1913 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN, CONST_PERSISTENT|CONST_CS);
1914 #endif
1915 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1916 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1917 #endif
1918 #ifdef ARES_AI_IDN_USE_STD
1919 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1920 #endif
1921 #ifdef ARES_AI_CANONIDN
1922 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN, CONST_PERSISTENT|CONST_CS);
1923 #endif
1924 #ifdef ARES_AI_MASK
1925 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK, CONST_PERSISTENT|CONST_CS);
1926 #endif
1927 #ifdef ARES_GETSOCK_MAXNUM
1928 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM, CONST_PERSISTENT|CONST_CS);
1929 #endif
1930
1931 /*
1932 * ns_t (type) constants (arpa/nameser.h)
1933 */
1934 #ifdef T_A
1935 /* (1) Host address. */
1936 REGISTER_LONG_CONSTANT("ARES_T_A", T_A, CONST_CS|CONST_PERSISTENT);
1937 #endif
1938 #ifdef T_NS
1939 /* (2) Authoritative server. */
1940 REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS, CONST_CS|CONST_PERSISTENT);
1941 #endif
1942 #ifdef T_MD
1943 /* (3) Mail destination. */
1944 REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD, CONST_CS|CONST_PERSISTENT);
1945 #endif
1946 #ifdef T_MF
1947 /* (4) Mail forwarder. */
1948 REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF, CONST_CS|CONST_PERSISTENT);
1949 #endif
1950 #ifdef T_CNAME
1951 /* (5) Canonical name. */
1952 REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME, CONST_CS|CONST_PERSISTENT);
1953 #endif
1954 #ifdef T_SOA
1955 /* (6) Start of authority zone. */
1956 REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA, CONST_CS|CONST_PERSISTENT);
1957 #endif
1958 #ifdef T_MB
1959 /* (7) Mailbox domain name. */
1960 REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB, CONST_CS|CONST_PERSISTENT);
1961 #endif
1962 #ifdef T_MG
1963 /* (8) Mail group member. */
1964 REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG, CONST_CS|CONST_PERSISTENT);
1965 #endif
1966 #ifdef T_MR
1967 /* (9) Mail rename name. */
1968 REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR, CONST_CS|CONST_PERSISTENT);
1969 #endif
1970 #ifdef T_NULL
1971 /* (10) Null resource record. */
1972 REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL, CONST_CS|CONST_PERSISTENT);
1973 #endif
1974 #ifdef T_WKS
1975 /* (11) Well known service. */
1976 REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS, CONST_CS|CONST_PERSISTENT);
1977 #endif
1978 #ifdef T_PTR
1979 /* (12) Domain name pointer. */
1980 REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR, CONST_CS|CONST_PERSISTENT);
1981 #endif
1982 #ifdef T_HINFO
1983 /* (13) Host information. */
1984 REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO, CONST_CS|CONST_PERSISTENT);
1985 #endif
1986 #ifdef T_MINFO
1987 /* (14) Mailbox information. */
1988 REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO, CONST_CS|CONST_PERSISTENT);
1989 #endif
1990 #ifdef T_MX
1991 /* (15) Mail routing information. */
1992 REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX, CONST_CS|CONST_PERSISTENT);
1993 #endif
1994 #ifdef T_TXT
1995 /* (16) Text strings. */
1996 REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT, CONST_CS|CONST_PERSISTENT);
1997 #endif
1998 #ifdef T_RP
1999 /* (17) Responsible person. */
2000 REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP, CONST_CS|CONST_PERSISTENT);
2001 #endif
2002 #ifdef T_AFSDB
2003 /* (18) AFS cell database. */
2004 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB, CONST_CS|CONST_PERSISTENT);
2005 #endif
2006 #ifdef T_X25
2007 /* (19) X_25 calling address. */
2008 REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25, CONST_CS|CONST_PERSISTENT);
2009 #endif
2010 #ifdef T_ISDN
2011 /* (20) ISDN calling address. */
2012 REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN, CONST_CS|CONST_PERSISTENT);
2013 #endif
2014 #ifdef T_RT
2015 /* (21) Router. */
2016 REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT, CONST_CS|CONST_PERSISTENT);
2017 #endif
2018 #ifdef T_NSAP
2019 /* (22) NSAP address. */
2020 REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP, CONST_CS|CONST_PERSISTENT);
2021 #endif
2022 #ifdef T_NSAP_PTR
2023 /* (23) Reverse NSAP lookup (deprecated). */
2024 REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR, CONST_CS|CONST_PERSISTENT);
2025 #endif
2026 #ifdef T_SIG
2027 /* (24) Security signature. */
2028 REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG, CONST_CS|CONST_PERSISTENT);
2029 #endif
2030 #ifdef T_KEY
2031 /* (25) Security key. */
2032 REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY, CONST_CS|CONST_PERSISTENT);
2033 #endif
2034 #ifdef T_PX
2035 /* (26) X.400 mail mapping. */
2036 REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX, CONST_CS|CONST_PERSISTENT);
2037 #endif
2038 #ifdef T_GPOS
2039 /* (27) Geographical position (withdrawn). */
2040 REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS, CONST_CS|CONST_PERSISTENT);
2041 #endif
2042 #ifdef T_AAAA
2043 /* (28) Ip6 Address. */
2044 REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA, CONST_CS|CONST_PERSISTENT);
2045 #endif
2046 #ifdef T_LOC
2047 /* (29) Location Information. */
2048 REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC, CONST_CS|CONST_PERSISTENT);
2049 #endif
2050 #ifdef T_NXT
2051 /* (30) Next domain (security). */
2052 REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT, CONST_CS|CONST_PERSISTENT);
2053 #endif
2054 #ifdef T_EID
2055 /* (31) Endpoint identifier. */
2056 REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID, CONST_CS|CONST_PERSISTENT);
2057 #endif
2058 #ifdef T_NIMLOC
2059 /* (32) Nimrod Locator. */
2060 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC, CONST_CS|CONST_PERSISTENT);
2061 #endif
2062 #ifdef T_SRV
2063 /* (33) Server Selection. */
2064 REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV, CONST_CS|CONST_PERSISTENT);
2065 #endif
2066 #ifdef T_ATMA
2067 /* (34) ATM Address */
2068 REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA, CONST_CS|CONST_PERSISTENT);
2069 #endif
2070 #ifdef T_NAPTR
2071 /* (35) Naming Authority Pointer */
2072 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR, CONST_CS|CONST_PERSISTENT);
2073 #endif
2074 #ifdef T_KX
2075 /* (36) Key Exchange */
2076 REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX, CONST_CS|CONST_PERSISTENT);
2077 #endif
2078 #ifdef T_CERT
2079 /* (37) Certification record */
2080 REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT, CONST_CS|CONST_PERSISTENT);
2081 #endif
2082 #ifdef T_A6
2083 /* (38) IPv6 address (deprecates AAAA) */
2084 REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6, CONST_CS|CONST_PERSISTENT);
2085 #endif
2086 #ifdef T_DNAME
2087 /* (39) Non-terminal DNAME (for IPv6) */
2088 REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME, CONST_CS|CONST_PERSISTENT);
2089 #endif
2090 #ifdef T_SINK
2091 /* (40) Kitchen sink (experimentatl) */
2092 REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK, CONST_CS|CONST_PERSISTENT);
2093 #endif
2094 #ifdef T_OPT
2095 /* (41) EDNS0 option (meta-RR) */
2096 REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT, CONST_CS|CONST_PERSISTENT);
2097 #endif
2098 #ifdef T_TSIG
2099 /* (250) Transaction signature. */
2100 REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG, CONST_CS|CONST_PERSISTENT);
2101 #endif
2102 #ifdef T_IXFR
2103 /* (251) Incremental zone transfer. */
2104 REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR, CONST_CS|CONST_PERSISTENT);
2105 #endif
2106 #ifdef T_AXFR
2107 /* (252) Transfer zone of authority. */
2108 REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR, CONST_CS|CONST_PERSISTENT);
2109 #endif
2110 #ifdef T_MAILB
2111 /* (253) Transfer mailbox records. */
2112 REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB, CONST_CS|CONST_PERSISTENT);
2113 #endif
2114 #ifdef T_MAILA
2115 /* (254) Transfer mail agent records. */
2116 REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA, CONST_CS|CONST_PERSISTENT);
2117 #endif
2118 #ifdef T_ANY
2119 /* (255) Wildcard match. */
2120 REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY, CONST_CS|CONST_PERSISTENT);
2121 #endif
2122
2123 /*
2124 * ns_c (dnsclass) constants (arpa/nameser.h)
2125 */
2126
2127 #ifdef C_IN
2128 /* (1) Internet. */
2129 REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN, CONST_CS|CONST_PERSISTENT);
2130 #endif
2131 #ifdef C_2
2132 /* (2) unallocated/unsupported. */
2133 REGISTER_LONG_CONSTANT("ARES_C_2", C_2, CONST_CS|CONST_PERSISTENT);
2134 #endif
2135 #ifdef C_CHAOS
2136 /* (3) MIT Chaos-net. */
2137 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS, CONST_CS|CONST_PERSISTENT);
2138 #endif
2139 #ifdef C_HS
2140 /* (4) MIT Hesiod. */
2141 REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS, CONST_CS|CONST_PERSISTENT);
2142 #endif
2143 #ifdef C_NONE
2144 /* (254) for prereq. sections in update requests */
2145 REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE, CONST_CS|CONST_PERSISTENT);
2146 #endif
2147 #ifdef C_ANY
2148 /* (255) Wildcard match. */
2149 REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY, CONST_CS|CONST_PERSISTENT);
2150 #endif
2151
2152 le_ares = zend_register_list_destructors_ex(php_ares_le_dtor, NULL, PHP_ARES_LE_NAME, module_number);
2153 le_ares_query = zend_register_list_destructors_ex(php_ares_query_le_dtor, NULL, PHP_ARES_QUERY_LE_NAME, module_number);
2154
2155 return SUCCESS;
2156 }
2157 /* }}} */
2158
2159 /* {{{ PHP_MSHUTDOWN_FUNCTION */
2160 static PHP_MSHUTDOWN_FUNCTION(ares)
2161 {
2162 #ifdef HAVE_ARES_LIBRARY_CLEANUP
2163 ares_library_cleanup();
2164 #endif
2165 return SUCCESS;
2166 }
2167 /* }}} */
2168
2169 /* {{{ PHP_MINFO_FUNCTION */
2170 static PHP_MINFO_FUNCTION(ares)
2171 {
2172 php_info_print_table_start();
2173 php_info_print_table_header(2, "AsyncResolver support", "enabled");
2174 php_info_print_table_row(2, "Version", PHP_ARES_VERSION);
2175 php_info_print_table_end();
2176
2177 php_info_print_table_start();
2178 php_info_print_table_header(3, "Used Library", "compiled", "linked");
2179 php_info_print_table_row(3,
2180 PHP_ARES_LIBNAME,
2181 #ifdef ARES_VERSION_STR
2182 ARES_VERSION_STR,
2183 #else
2184 "unkown",
2185 #endif
2186 #ifdef HAVE_ARES_VERSION
2187 ares_version(NULL)
2188 #else
2189 "unkown"
2190 #endif
2191 );
2192 php_info_print_table_end();
2193 }
2194 /* }}} */
2195
2196 #ifdef ZEND_ENGINE_2
2197 ZEND_BEGIN_ARG_INFO(ai_ares_select, 0)
2198 ZEND_ARG_PASS_INFO(1)
2199 ZEND_ARG_PASS_INFO(1)
2200 ZEND_ARG_PASS_INFO(0)
2201 ZEND_END_ARG_INFO();
2202
2203 ZEND_BEGIN_ARG_INFO(ai_ares_result, 0)
2204 ZEND_ARG_PASS_INFO(0)
2205 ZEND_ARG_PASS_INFO(1)
2206 ZEND_ARG_PASS_INFO(1)
2207 ZEND_END_ARG_INFO();
2208
2209 ZEND_BEGIN_ARG_INFO(ai_ares_fds, 0)
2210 ZEND_ARG_PASS_INFO(0)
2211 ZEND_ARG_PASS_INFO(1)
2212 ZEND_ARG_PASS_INFO(1)
2213 ZEND_END_ARG_INFO();
2214 #else
2215 static unsigned char ai_ares_select[] = {3, BYREF_FORCE, BYREF_FORCE, BYREF_NONE};
2216 static unsigned char ai_ares_result[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2217 static unsigned char ai_ares_fds[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
2218 #endif
2219
2220 /* {{{ ares_functions[] */
2221 zend_function_entry ares_functions[] = {
2222 #ifdef HAVE_ARES_VERSION
2223 PHP_FE(ares_version, NULL)
2224 #endif
2225 PHP_FE(ares_init, NULL)
2226 PHP_FE(ares_destroy, NULL)
2227 PHP_FE(ares_strerror, NULL)
2228 #ifdef HAVE_ARES_CANCEL
2229 PHP_FE(ares_cancel, NULL)
2230 #endif
2231 PHP_FE(ares_search, NULL)
2232 PHP_FE(ares_query, NULL)
2233 PHP_FE(ares_send, NULL)
2234 PHP_FE(ares_mkquery, NULL)
2235 PHP_FE(ares_gethostbyname, NULL)
2236 PHP_FE(ares_gethostbyaddr, NULL)
2237 #ifdef HAVE_ARES_GETNAMEINFO
2238 PHP_FE(ares_getnameinfo, NULL)
2239 #endif
2240 PHP_FE(ares_result, ai_ares_result)
2241 PHP_FE(ares_packet, NULL)
2242 PHP_FE(ares_process_all, NULL)
2243 PHP_FE(ares_process_once, NULL)
2244 PHP_FE(ares_process, NULL)
2245 PHP_FE(ares_select, ai_ares_select)
2246 PHP_FE(ares_fds, ai_ares_fds)
2247 PHP_FE(ares_timeout, NULL)
2248 {NULL, NULL, NULL}
2249 };
2250 /* }}} */
2251
2252 /* {{{ ares_module_entry */
2253 zend_module_entry ares_module_entry = {
2254 STANDARD_MODULE_HEADER,
2255 "ares",
2256 ares_functions,
2257 PHP_MINIT(ares),
2258 PHP_MSHUTDOWN(ares),
2259 NULL,
2260 NULL,
2261 PHP_MINFO(ares),
2262 PHP_ARES_VERSION,
2263 STANDARD_MODULE_PROPERTIES
2264 };
2265 /* }}} */
2266
2267 #ifdef COMPILE_DL_ARES
2268 ZEND_GET_MODULE(ares)
2269 #endif
2270
2271 /*
2272 * Local variables:
2273 * tab-width: 4
2274 * c-basic-offset: 4
2275 * End:
2276 * vim600: noet sw=4 ts=4 fdm=marker
2277 * vim<600: noet sw=4 ts=4
2278 */