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