2 +--------------------------------------------------------------------+
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 +--------------------------------------------------------------------+
21 #include "php_streams.h"
22 #include "ext/standard/info.h"
26 #ifdef HAVE_ARES_VERSION
27 # include <ares_version.h>
35 #ifdef HAVE_ARPA_INET_H
36 # include <arpa/inet.h>
38 #ifdef HAVE_ARPA_NAMESER_H
39 # include <arpa/nameser.h>
41 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42 # include <arpa/nameser_compat.h>
45 #define local static inline
48 # define PHP_ARES_IS_CALLABLE(a,b,c) 1
50 # undef TSRMLS_SET_CTX
51 # define TSRMLS_SET_CTX
52 # undef TSRMLS_FETCH_FROM_CTX
53 # define TSRMLS_FETCH_FROM_CTX
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)
60 # define ADDREF(z) ZVAL_ADDREF(z)
61 # define PHP_ARES_IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
64 #define PHP_ARES_LE_NAME "AsyncResolver"
65 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
67 static int le_ares_query
;
69 static const char *php_ares_C_names
[] = {
75 "","","","","","","","","","","","","","","","","","","","", /* 20x */
76 "","","","","","","","","","","","","","","","","","","","", /* 20x */
77 "","","","","","","","","","","","","","","","","","","","", /* 20x */
78 "","","","","","","","","","","","","","","","","","","","", /* 20x */
79 "","","","","","","","","","","","","","","","","","","","", /* 20x */
80 "","","","","","","","","","","","","","","","","","","","", /* 20x */
81 "","","","","","","","","","","","","","","","","","","","", /* 20x */
82 "","","","","","","","","","","","","","","","","","","","", /* 20x */
83 "","","","","","","","","","","","","","","","","","","","", /* 20x */
84 "","","","","","","","","","","","","","","","","","","","", /* 20x */
85 "","","","","","","","","","","","","","","","","","","","", /* 20x */
86 "","","","","","","","","", /* 9x */
91 static const char *php_ares_T_names
[] = {
135 "","","","","","","","","","","","","","","","","","","","", /* 20x */
136 "","","","","","","","","","","","","","","","","","","","", /* 20x */
137 "","","","","","","","","","","","","","","","","","","","", /* 20x */
138 "","","","","","","","","","","","","","","","","","","","", /* 20x */
139 "","","","","","","","","","","","","","","","","","","","", /* 20x */
140 "","","","","","","","","","","","","","","","","","","","", /* 20x */
141 "","","","","","","","","","","","","","","","","","","","", /* 20x */
142 "","","","","","","","","","","","","","","","","","","","", /* 20x */
143 "","","","","","","","","","","","","","","","","","","","", /* 20x */
144 "","","","","","","","","","","","","","","","","","","","", /* 20x */
145 "","","","","","", /* 6x */
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); \
163 # define PHP_ARES_ERROR(err) \
164 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
167 #define RETURN_ARES_ERROR(err) \
168 PHP_ARES_ERROR(err); \
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); \
176 #define PHP_ARES_QUERY_BUFFER_LEN 2<<0xf
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
)
182 return dst
== ares_inet_pton(af
, src
, dst
, size
);
186 #ifdef HAVE_ARES_INET_NTOP
187 # define inet_ntop ares_inet_ntop
191 typedef struct _php_ares_options
{
192 struct ares_options strct
;
196 typedef struct _php_ares
{
197 ares_channel channel
;
198 php_ares_options options
;
201 unsigned in_callback
:1;
202 unsigned reserved
:31;
205 typedef enum _php_ares_query_type
{
209 } php_ares_query_type
;
211 typedef enum _php_ares_query_packet_type
{
212 PHP_ARES_PCKT_SEARCH
,
218 } php_ares_query_packet_type
;
220 typedef union _php_ares_query_packet_data
{
254 } php_ares_query_packet_data
;
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
;
261 typedef union _php_ares_query_result
{
272 } php_ares_query_result
;
274 typedef struct _php_ares_query
{
279 php_ares_query_type type
;
280 php_ares_query_packet packet
;
281 php_ares_query_result result
;
285 local
struct hostent
*php_ares_hostent_ctor(struct hostent
*host
) /* {{{ */
288 host
= emalloc(sizeof(struct hostent
));
290 memset(host
, 0, sizeof(struct hostent
));
296 local
void php_ares_hostent_copy(struct hostent
*from
, struct hostent
*to
) /* {{{ */
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
]);
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
);
317 local
void php_ares_hostent_to_struct(struct hostent
*hostent
, HashTable
*ht
) /* {{{ */
323 Z_TYPE(array
) = IS_ARRAY
;
324 Z_ARRVAL(array
) = ht
;
327 add_assoc_string(&array
, "name", hostent
->h_name
, 1);
331 if (hostent
->h_aliases
) {
332 for (ptr
= hostent
->h_aliases
; *ptr
; ++ptr
) {
333 add_next_index_string(tmp
, *ptr
, 1);
336 add_assoc_zval(&array
, "aliases", tmp
);
337 add_assoc_long(&array
, "addrtype", hostent
->h_addrtype
);
341 if (hostent
->h_addr_list
) {
342 for (ptr
= hostent
->h_addr_list
; *ptr
; ++ptr
) {
345 if (inet_ntop(hostent
->h_addrtype
, *ptr
, name
, sizeof(name
)-1)) {
346 add_next_index_string(tmp
, name
, 1);
350 add_assoc_zval(&array
, "addrlist", tmp
);
355 local
void php_ares_hostent_dtor(struct hostent
*host
) /* {{{ */
359 STR_FREE(host
->h_name
);
360 if (host
->h_aliases
) {
361 for (ptr
= host
->h_aliases
; *ptr
; ++ptr
) {
364 efree(host
->h_aliases
);
366 if (host
->h_addr_list
) {
367 for (ptr
= host
->h_addr_list
; *ptr
; ++ptr
) {
370 efree(host
->h_addr_list
);
372 memset(host
, 0, sizeof(struct hostent
));
376 local
void php_ares_hostent_free(struct hostent
**host
) /* {{{ */
378 php_ares_hostent_dtor(*host
);
384 local php_ares_query
*php_ares_query_ctor(php_ares_query
*query
, php_ares_query_type type
, php_ares
*ares
, zval
*callback
) /* {{{ */
387 query
= emalloc(sizeof(php_ares_query
));
389 memset(query
, 0, sizeof(php_ares_query
));
397 query
->callback
= callback
;
404 local
void php_ares_query_rsrc(php_ares_query
*query
, zval
*return_value
) /* {{{ */
406 TSRMLS_FETCH_FROM_CTX(query
->ares
->tsrm_ls
);
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
);
415 local
void php_ares_query_pckt(php_ares_query
*query
, php_ares_query_packet_type type
, ...)
421 va_start(argv
, type
);
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);
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);
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
;
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);
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);
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);
479 local
void php_ares_query_dtor(php_ares_query
*query
) /* {{{ */
481 struct php_ares_query_packet_buf
{char *buf
;} *packet
;
483 packet
= (struct php_ares_query_packet_buf
*) &query
->packet
.data
;
487 switch (query
->type
) {
488 case PHP_ARES_CB_STD
:
489 if (query
->result
.std
.arr
) {
490 zval_ptr_dtor(&query
->result
.std
.arr
);
492 STR_FREE(query
->result
.std
.buf
);
494 case PHP_ARES_CB_HOST
:
495 php_ares_hostent_dtor(&query
->result
.host
);
497 case PHP_ARES_CB_NINFO
:
498 STR_FREE(query
->result
.ninfo
.service
);
499 STR_FREE(query
->result
.ninfo
.node
);
502 if (query
->callback
) {
503 zval_ptr_dtor(&query
->callback
);
505 memset(query
, 0, sizeof(php_ares_query
));
509 local
void php_ares_query_free(php_ares_query
**query
) /* {{{ */
511 php_ares_query_dtor(*query
);
517 local zend_bool
is_numeric(zval
**p
, long *lval
) { /* {{{ */
519 switch (Z_TYPE_PP(p
)) {
521 convert_to_long_ex(&tmp
);
524 *lval
= Z_LVAL_P(tmp
);
533 local php_ares_options
*php_ares_options_ctor(php_ares_options
*options
, HashTable
*ht
) /* {{{ */
540 options
= emalloc(sizeof(php_ares_options
));
542 memset(options
, 0, sizeof(php_ares_options
));
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
;
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
;
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
;
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
;
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
;
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
;
572 options
->strct
.udp_port
= htons((unsigned short) lval
);
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
;
580 options
->strct
.tcp_port
= htons((unsigned short) lval
);
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
++]);
592 if (options
->strct
.nservers
) {
593 options
->flags
|= ARES_OPT_SERVERS
;
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
));
605 if (options
->strct
.ndomains
) {
606 options
->flags
|= ARES_OPT_DOMAINS
;
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
));
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
;
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
;
630 local
void php_ares_options_dtor(php_ares_options
*options
) /* {{{ */
634 if (options
->strct
.servers
) {
635 efree(options
->strct
.servers
);
638 if (options
->strct
.domains
) {
639 for (i
= 0; i
< options
->strct
.ndomains
; ++i
) {
640 efree(options
->strct
.domains
[i
]);
642 efree(options
->strct
.domains
);
645 STR_FREE(options
->strct
.lookups
);
647 memset(options
, 0, sizeof(php_ares_options
));
651 local
void php_ares_options_free(php_ares_options
**options
) /* {{{ */
653 php_ares_options_dtor(*options
);
659 local PHP_ARES_EXPAND_LEN_TYPE
php_ares_skip(const unsigned char *pointer
, const unsigned char *abuf
, int alen TSRMLS_DC
)
663 PHP_ARES_EXPAND_LEN_TYPE byte_count
;
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
);
676 local
int php_ares_parse_record(const unsigned char *abuf
, const int alen
, const unsigned char **rptr
, zval
*result TSRMLS_DC
)
678 uint16_t stmp
, type
, class;
681 PHP_ARES_EXPAND_LEN_TYPE byte_count
;
682 const unsigned char *pointer
= *rptr
;
686 if (0 > (byte_count
= php_ares_skip(pointer
, abuf
, alen TSRMLS_CC
))) {
690 pointer
+= byte_count
;
692 MAKE_STD_ZVAL(entry
);
695 GETSHORT(type
, pointer
);
696 add_assoc_string(entry
, "type", estrdup(php_ares_T_names
[type
]), 0);
697 GETSHORT(class, pointer
);
698 add_assoc_string(entry
, "class", estrdup(php_ares_C_names
[class]), 0);
699 GETLONG(ttl
, pointer
);
700 add_assoc_long(entry
, "ttl", ttl
);
701 GETSHORT(byte_count
, pointer
);
703 fprintf(stderr
, ">> processing %s answer of length %d\n", php_ares_T_names
[type
], byte_count
);
707 name
= ecalloc(1, 16);
708 inet_ntop(AF_INET
, pointer
, name
, 16);
709 add_assoc_string(entry
, "addr", name
, 0);
710 pointer
+= byte_count
;
714 name
= ecalloc(1, 48);
715 inet_ntop(AF_INET6
, pointer
, name
, 48);
716 add_assoc_string(entry
, "addr", name
, 0);
717 pointer
+= byte_count
;
724 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
728 pointer
+= byte_count
;
729 add_assoc_string(entry
, "name", name
, 1);
730 ares_free_string(name
);
734 GETSHORT(stmp
, pointer
);
735 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
739 pointer
+= byte_count
;
740 add_assoc_long(entry
, "weight", stmp
);
741 add_assoc_string(entry
, "name", name
, 1);
742 ares_free_string(name
);
746 GETSHORT(stmp
, pointer
);
747 add_assoc_long(entry
, "priority", stmp
);
748 GETSHORT(stmp
, pointer
);
749 add_assoc_long(entry
, "weight", stmp
);
750 GETSHORT(stmp
, pointer
);
751 add_assoc_long(entry
, "port", stmp
);
753 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
755 zval_ptr_dtor(&entry
);
758 pointer
+= byte_count
;
759 add_assoc_string(entry
, "name", name
, 1);
760 ares_free_string(name
);
764 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
766 zval_ptr_dtor(&entry
);
769 pointer
+= byte_count
;
770 add_assoc_string(entry
, "name", name
, 1);
771 ares_free_string(name
);
773 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
775 zval_ptr_dtor(&entry
);
778 pointer
+= byte_count
;
779 add_assoc_string(entry
, "mail", name
, 1);
780 ares_free_string(name
);
782 GETLONG(ltmp
, pointer
);
783 add_assoc_long(entry
, "serial", ltmp
);
784 GETLONG(ltmp
, pointer
);
785 add_assoc_long(entry
, "refresh", ltmp
);
786 GETLONG(ltmp
, pointer
);
787 add_assoc_long(entry
, "retry", ltmp
);
788 GETLONG(ltmp
, pointer
);
789 add_assoc_long(entry
, "expire", ltmp
);
790 GETLONG(ltmp
, pointer
);
791 add_assoc_long(entry
, "minimum-ttl", ltmp
);
795 for (ltmp
= 0; ltmp
< byte_count
; ltmp
+= pointer
[ltmp
] + 1) {
796 add_next_index_stringl(entry
, (const char *) &pointer
[ltmp
+ 1], pointer
[ltmp
], 1);
798 pointer
+= byte_count
;
802 #ifndef HAVE_INET_PTON
805 zval_ptr_dtor(&entry
);
807 pointer
+= byte_count
;
812 add_next_index_zval(result
, entry
);
818 local
int php_ares_parse(const unsigned char *abuf
, int alen
, zval
*result TSRMLS_DC
) /* {{{ */
821 PHP_ARES_EXPAND_LEN_TYPE byte_count
;
822 const unsigned char *pointer
;
823 int query_count
, answer_count
, auth_count
, other_count
;
825 convert_to_array(result
);
827 if (!alen
|| !abuf
|| !*abuf
) {
831 header
= (HEADER
*) abuf
;
832 pointer
= abuf
+ HFIXEDSZ
;
834 for (query_count
= ntohs(header
->qdcount
); query_count
--; pointer
+= byte_count
+ QFIXEDSZ
) {
835 if (0 > (byte_count
= php_ares_skip(pointer
, abuf
, alen TSRMLS_CC
))) {
840 for (answer_count
= ntohs(header
->ancount
); answer_count
-- && pointer
< (abuf
+ alen
); ) {
841 if (SUCCESS
!= php_ares_parse_record(abuf
, alen
, &pointer
, result TSRMLS_CC
)) {
846 for (auth_count
= ntohs(header
->nscount
); auth_count
-- && pointer
< (abuf
+ alen
); ) {
847 if (SUCCESS
!= php_ares_parse_record(abuf
, alen
, &pointer
, result TSRMLS_CC
)) {
852 for (other_count
= ntohs(header
->arcount
); other_count
-- && pointer
< (abuf
+ alen
); ) {
853 if (SUCCESS
!= php_ares_parse_record(abuf
, alen
, &pointer
, result TSRMLS_CC
)) {
863 static void php_ares_callback_func_old(void *aq
, int status
, unsigned char *abuf
, int alen
)
865 php_ares_query
*q
= (php_ares_query
*) aq
;
866 zval
*params
[4], *retval
, *parsed
= NULL
;
867 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
871 q
->result
.std
.buf
= estrndup((char *) abuf
, alen
);
872 q
->result
.std
.len
= alen
;
874 MAKE_STD_ZVAL(parsed
);
876 if (SUCCESS
== php_ares_parse(abuf
, alen
, parsed TSRMLS_CC
)) {
877 q
->result
.std
.arr
= parsed
;
879 zval_ptr_dtor(&parsed
);
885 MAKE_STD_ZVAL(retval
);
886 MAKE_STD_ZVAL(params
[0]);
887 MAKE_STD_ZVAL(params
[1]);
888 MAKE_STD_ZVAL(params
[2]);
890 zend_list_addref(q
->id
);
891 Z_LVAL_P(params
[0]) = q
->id
;
892 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
893 ZVAL_LONG(params
[1], status
);
894 ZVAL_STRINGL(params
[2], (char *) abuf
, alen
, 1);
901 q
->ares
->in_callback
= 1;
902 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, parsed
? 4 : 3, params TSRMLS_CC
);
903 q
->ares
->in_callback
= 0;
905 zval_ptr_dtor(&retval
);
906 zval_ptr_dtor(¶ms
[0]);
907 zval_ptr_dtor(¶ms
[1]);
908 zval_ptr_dtor(¶ms
[2]);
911 zval_ptr_dtor(¶ms
[3]);
916 static void php_ares_host_callback_func_old(void *aq
, int status
, struct hostent
*hostent
)
918 php_ares_query
*q
= (php_ares_query
*) aq
;
919 zval
*params
[3], *retval
;
920 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
924 php_ares_hostent_copy(hostent
, &q
->result
.host
);
928 MAKE_STD_ZVAL(retval
);
929 MAKE_STD_ZVAL(params
[0]);
930 MAKE_STD_ZVAL(params
[1]);
931 MAKE_STD_ZVAL(params
[2]);
933 zend_list_addref(q
->id
);
934 Z_LVAL_P(params
[0]) = q
->id
;
935 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
936 ZVAL_LONG(params
[1], status
);
937 object_init(params
[2]);
938 php_ares_hostent_to_struct(hostent
, HASH_OF(params
[2]));
940 q
->ares
->in_callback
= 1;
941 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 3, params TSRMLS_CC
);
942 q
->ares
->in_callback
= 0;
944 zval_ptr_dtor(&retval
);
945 zval_ptr_dtor(¶ms
[0]);
946 zval_ptr_dtor(¶ms
[1]);
947 zval_ptr_dtor(¶ms
[2]);
951 #ifdef HAVE_ARES_GETNAMEINFO
952 static void php_ares_nameinfo_callback_func_old(void *aq
, int status
, char *node
, char *service
)
954 php_ares_query
*q
= (php_ares_query
*) aq
;
955 zval
*params
[4], *retval
;
956 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
960 q
->result
.ninfo
.node
= estrdup(node
);
963 q
->result
.ninfo
.service
= estrdup(service
);
967 MAKE_STD_ZVAL(retval
);
968 MAKE_STD_ZVAL(params
[0]);
969 MAKE_STD_ZVAL(params
[1]);
970 MAKE_STD_ZVAL(params
[2]);
971 MAKE_STD_ZVAL(params
[3]);
973 zend_list_addref(q
->id
);
974 Z_LVAL_P(params
[0]) = q
->id
;
975 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
976 ZVAL_LONG(params
[1], status
);
978 ZVAL_STRING(params
[2], node
, 1);
980 ZVAL_NULL(params
[2]);
983 ZVAL_STRING(params
[3], service
, 1);
985 ZVAL_NULL(params
[3]);
988 q
->ares
->in_callback
= 1;
989 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 4, params TSRMLS_CC
);
990 q
->ares
->in_callback
= 0;
992 zval_ptr_dtor(&retval
);
993 zval_ptr_dtor(¶ms
[0]);
994 zval_ptr_dtor(¶ms
[1]);
995 zval_ptr_dtor(¶ms
[2]);
996 zval_ptr_dtor(¶ms
[3]);
1001 #if PHP_ARES_NEW_CALLBACK_API
1002 # define php_ares_callback_func php_ares_callback_func_new
1003 static void php_ares_callback_func_new(void *aq
, int status
, int timeouts
, unsigned char *abuf
, int alen
)
1005 php_ares_callback_func_old(aq
, status
, abuf
, alen
);
1008 # define php_ares_host_callback_func php_ares_host_callback_func_new
1009 static void php_ares_host_callback_func_new(void *aq
, int status
, int timeouts
, struct hostent
*hostent
)
1011 php_ares_host_callback_func_old(aq
, status
, hostent
);
1014 # ifdef HAVE_ARES_GETNAMEINFO
1015 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
1016 static void php_ares_nameinfo_callback_func_new(void *aq
, int status
, int timeouts
, char *node
, char *service
)
1018 php_ares_nameinfo_callback_func_old(aq
, status
, node
, service
);
1023 # define php_ares_callback_func php_ares_callback_func_old
1024 # define php_ares_host_callback_func php_ares_host_callback_func_old
1025 # ifdef HAVE_ARES_GETNAMEINFO
1026 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
1031 local
struct timeval
*php_ares_timeout(php_ares
*ares
, long max_timeout
, struct timeval
*tv_buf
) /* {{{ */
1033 struct timeval maxtv
;
1035 if (max_timeout
> -1) {
1036 maxtv
.tv_sec
= max_timeout
/ 1000;
1037 maxtv
.tv_usec
= max_timeout
% (max_timeout
* 1000);
1040 return ares_timeout(ares
->channel
, max_timeout
> -1 ? &maxtv
: NULL
, tv_buf
);
1044 local
int php_ares_process(php_ares
*ares
, long max_timeout
) /* {{{ */
1053 if ((nfds
= ares_fds(ares
->channel
, &R
, &W
))) {
1054 if (0 < select(nfds
, &R
, &W
, NULL
, php_ares_timeout(ares
, max_timeout
, &tv
))) {
1055 ares_process(ares
->channel
, &R
, &W
);
1063 local
int php_ares_publish_fds(fd_set
*R
, fd_set
*W
, zval
*r
, zval
*w
, HashTable
*resource_map
) /* {{{ */
1068 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
1069 if (FD_ISSET(i
, R
)) {
1070 if (resource_map
&& (SUCCESS
== zend_hash_index_find(resource_map
, i
, (void *) &fd
))) {
1072 add_next_index_zval(r
, *fd
);
1074 add_next_index_long(r
, i
);
1082 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
1083 if (FD_ISSET(i
, W
)) {
1084 if (resource_map
&& (SUCCESS
== zend_hash_index_find(resource_map
, i
, (void *) &fd
))) {
1086 add_next_index_zval(r
, *fd
);
1088 add_next_index_long(w
, i
);
1096 return nfds
? nfds
+ 1 : 0;
1100 local
int php_ares_extract_fds(zval
*r
, zval
*w
, fd_set
*R
, fd_set
*W
, HashTable
*resource_map TSRMLS_DC
) /* {{{ */
1107 Z_ARRVAL(zmap
) = resource_map
;
1108 Z_TYPE(zmap
) = IS_ARRAY
;
1109 if (r
&& zend_hash_num_elements(Z_ARRVAL_P(r
))) {
1110 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r
));
1111 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(r
), (void *) &fd
);
1112 zend_hash_move_forward(Z_ARRVAL_P(r
))) {
1113 if (Z_TYPE_PP(fd
) == IS_RESOURCE
) {
1114 php_stream
*s
= NULL
;
1117 ZEND_FETCH_RESOURCE_NO_RETURN(s
, php_stream
*, fd
, -1, NULL
, php_file_le_stream());
1118 if (s
&& (SUCCESS
== php_stream_cast(s
, PHP_STREAM_AS_FD_FOR_SELECT
, (void *) &id
, 1))) {
1120 add_index_zval(&zmap
, id
, *fd
);
1126 } else if (Z_TYPE_PP(fd
) == IS_LONG
) {
1127 FD_SET(Z_LVAL_PP(fd
), R
);
1128 if (Z_LVAL_PP(fd
) > nfds
) {
1129 nfds
= Z_LVAL_PP(fd
);
1135 if (w
&& zend_hash_num_elements(Z_ARRVAL_P(w
))) {
1136 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w
));
1137 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(w
), (void *) &fd
);
1138 zend_hash_move_forward(Z_ARRVAL_P(w
))) {
1139 if (Z_TYPE_PP(fd
) == IS_RESOURCE
) {
1140 php_stream
*s
= NULL
;
1143 ZEND_FETCH_RESOURCE_NO_RETURN(s
, php_stream
*, fd
, -1, NULL
, php_file_le_stream());
1144 if (s
&& (SUCCESS
== php_stream_cast(s
, PHP_STREAM_AS_FD_FOR_SELECT
, (void *) &id
, 1))) {
1146 add_index_zval(&zmap
, id
, *fd
);
1152 } else if (Z_TYPE_PP(fd
) == IS_LONG
) {
1153 FD_SET(Z_LVAL_PP(fd
), W
);
1154 if (Z_LVAL_PP(fd
) > nfds
) {
1155 nfds
= Z_LVAL_PP(fd
);
1161 return nfds
? nfds
+ 1 : 0;
1165 static void php_ares_query_llist_dtor(void *entry
)
1167 php_ares_query
*q
= *(php_ares_query
**) entry
;
1168 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
1169 zend_list_delete(q
->id
);
1172 #ifdef HAVE_ARES_VERSION
1173 /* {{{ proto string ares_version()
1174 Get libares version */
1175 static PHP_FUNCTION(ares_version
)
1177 if (ZEND_NUM_ARGS()) {
1181 RETURN_STRING(estrdup(ares_version(NULL
)), 0);
1186 /* {{{ proto resource ares_init([array options])
1187 Create an ares resource */
1188 static PHP_FUNCTION(ares_init
)
1190 zval
*opt_array
= NULL
;
1191 php_ares
*ares
= NULL
;
1194 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &opt_array
)) {
1198 ares
= ecalloc(1, sizeof(php_ares
));
1199 TSRMLS_SET_CTX(ares
->tsrm_ls
);
1200 zend_llist_init(&ares
->queries
, sizeof(php_ares_query
*), (llist_dtor_func_t
) php_ares_query_llist_dtor
, 0);
1201 php_ares_options_ctor(&ares
->options
, opt_array
? Z_ARRVAL_P(opt_array
) : NULL
);
1203 if (ARES_SUCCESS
!= (err
= ares_init_options(&ares
->channel
, &ares
->options
.strct
, ares
->options
.flags
))) {
1204 php_ares_options_dtor(&ares
->options
);
1205 zend_llist_destroy(&ares
->queries
);
1207 RETURN_ARES_ERROR(err
);
1210 ZEND_REGISTER_RESOURCE(return_value
, ares
, le_ares
);
1214 #ifdef HAVE_ARES_SET_LOCAL_DEV
1215 /* {{{ proto void ares_set_local_dev(resource ares, string dev)
1216 Set the local interface name to bind to. */
1217 static PHP_FUNCTION(ares_set_local_dev
)
1220 char *dev_str
= NULL
;
1224 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rs!", &rsrc
, &dev_str
, &dev_len
)) {
1227 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1229 ares_set_local_dev(ares
->channel
, dev_str
);
1233 #ifdef HAVE_ARES_SET_LOCAL_IP4
1234 /* {{{ proto void ares_set_local_ip4(resource ares, int addr)
1235 Set the local IPv4 address to bind to. */
1236 static PHP_FUNCTION(ares_set_local_ip4
)
1242 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rl", &rsrc
, &ip4_num
)) {
1245 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1247 ares_set_local_ip4(ares
->channel
, (unsigned int) ip4_num
);
1251 #ifdef HAVE_ARES_SET_LOCAL_IP6
1252 /* {{{ proto void ares_set_local_ip6(resource ares, string addr128bit)
1253 Set the local IPv6 address to bind to. */
1254 static PHP_FUNCTION(ares_set_local_ip6
)
1261 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rs", &rsrc
, &ip6_str
, &ip6_len
)) {
1264 if (16 != ip6_len
) {
1265 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Binary IPv6 address string must be exactly 16 bytes long");
1267 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1269 ares_set_local_ip6(ares
->channel
, (unsigned char *) ip6_str
);
1273 /* {{{ proto void ares_destroy(resource ares)
1274 Destroy the ares handle */
1275 static PHP_FUNCTION(ares_destroy
)
1280 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1281 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1282 if (ares
->in_callback
) {
1283 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Cannot destroy ares handle while in callback");
1285 zend_list_delete(Z_LVAL_P(rsrc
));
1291 /* {{{ proto string ares_strerror(int status)
1292 Get description of status code */
1293 static PHP_FUNCTION(ares_strerror
)
1296 #ifdef HAVE_OLD_ARES_STRERROR
1301 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &err
)) {
1305 #ifdef HAVE_OLD_ARES_STRERROR
1306 __err
= ares_strerror(err
, &__tmp
);
1307 RETVAL_STRING(estrdup(__err
), 0);
1309 ares_free_errmem(__tmp
);
1312 RETURN_STRING(estrdup(ares_strerror(err
)), 0);
1317 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
1318 Compose a custom query */
1319 static PHP_FUNCTION(ares_mkquery
)
1321 char *name_str
, *query_str
;
1322 int name_len
, query_len
, err
;
1323 long dnsclass
, type
, id
, rd
;
1325 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sllll", &name_str
, &name_len
, &dnsclass
, &type
, &id
, &rd
)) {
1329 if (ARES_SUCCESS
!= (err
= ares_mkquery(name_str
, dnsclass
, type
, id
, rd
, (unsigned char **) &query_str
, &query_len
))) {
1330 RETURN_ARES_ERROR(err
);
1332 RETVAL_STRINGL(query_str
, query_len
, 1);
1333 ares_free_string(query_str
);
1337 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1338 Issue a domain search for name */
1339 static PHP_FUNCTION(ares_search
)
1341 zval
*rsrc
, *cb
= NULL
;
1343 php_ares_query
*query
;
1346 long dnsclass
= C_IN
, type
= T_A
;
1348 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
1351 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1353 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1354 RETURN_ARES_CB_ERROR("second");
1357 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1358 php_ares_query_rsrc(query
, return_value
);
1359 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEARCH
, name
, name_len
, type
, dnsclass
);
1360 ares_search(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
1364 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1365 Issue a single DNS query */
1366 static PHP_FUNCTION(ares_query
)
1368 zval
*rsrc
, *cb
= NULL
;
1370 php_ares_query
*query
;
1373 long dnsclass
= C_IN
, type
= T_A
;
1375 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
1378 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1380 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1381 RETURN_ARES_CB_ERROR("second");
1384 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1385 php_ares_query_rsrc(query
, return_value
);
1386 php_ares_query_pckt(query
, PHP_ARES_PCKT_QUERY
, name
, name_len
, type
, dnsclass
);
1387 ares_query(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
1391 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
1392 Send custom query */
1393 static PHP_FUNCTION(ares_send
)
1395 zval
*rsrc
, *cb
= NULL
;
1397 php_ares_query
*query
;
1401 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s", &rsrc
, &cb
, &buf
, &len
)) {
1404 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1406 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1407 RETURN_ARES_CB_ERROR("second");
1410 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1411 php_ares_query_rsrc(query
, return_value
);
1412 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEND
, buf
, len
);
1413 ares_send(ares
->channel
, (const unsigned char *) buf
, len
, php_ares_callback_func
, query
);
1417 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
1419 static PHP_FUNCTION(ares_gethostbyname
)
1421 zval
*rsrc
, *cb
= NULL
;
1423 php_ares_query
*query
;
1426 long family
= AF_INET
;
1428 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &name
, &name_len
, &family
)) {
1431 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1433 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1434 RETURN_ARES_CB_ERROR("second");
1437 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
1438 php_ares_query_rsrc(query
, return_value
);
1439 php_ares_query_pckt(query
, PHP_ARES_PCKT_HNAME
, name
, name_len
, family
);
1440 ares_gethostbyname(ares
->channel
, name
, family
, php_ares_host_callback_func
, query
);
1444 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
1445 Get host by address */
1446 static PHP_FUNCTION(ares_gethostbyaddr
)
1448 zval
*rsrc
, *cb
= NULL
;
1450 php_ares_query
*query
;
1453 long family
= AF_INET
;
1457 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &addr
, &addr_len
, &family
)) {
1460 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1462 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1463 PHP_ARES_CB_ERROR("second");
1469 sa
= emalloc(sa_len
= sizeof(struct in_addr
));
1472 sa
= emalloc(sa_len
= sizeof(struct in6_addr
));
1475 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1480 if (1 > inet_pton(family
, addr
, sa
)) {
1481 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1484 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
1485 php_ares_query_rsrc(query
, return_value
);
1486 php_ares_query_pckt(query
, PHP_ARES_PCKT_HADDR
, addr
, addr_len
, family
);
1487 ares_gethostbyaddr(ares
->channel
, sa
, sa_len
, family
, php_ares_host_callback_func
, query
);
1493 #ifdef HAVE_ARES_GETNAMEINFO
1494 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1496 static PHP_FUNCTION(ares_getnameinfo
)
1498 zval
*rsrc
, *cb
= NULL
;
1500 php_ares_query
*query
;
1503 long flags
, port
= 0, family
= AF_INET
;
1504 struct sockaddr
*sa
;
1505 struct sockaddr_in
*in
;
1506 struct sockaddr_in6
*in6
;
1509 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!ls|ll", &rsrc
, &cb
, &flags
, &addr
, &addr_len
, &family
, &port
)) {
1512 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1514 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1515 PHP_ARES_CB_ERROR("second");
1522 in
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in
));
1523 in
->sin_family
= AF_INET
;
1524 in
->sin_port
= htons((unsigned short) port
);
1525 if (1 > inet_pton(in
->sin_family
, addr
, &in
->sin_addr
)) {
1526 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1529 sa
= (struct sockaddr
*) in
;
1532 in6
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in6
));
1533 in6
->sin6_family
= AF_INET6
;
1534 in6
->sin6_port
= htons((unsigned short) port
);
1535 if (1 > inet_pton(in6
->sin6_family
, addr
, &in6
->sin6_addr
)) {
1536 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1539 sa
= (struct sockaddr
*) in6
;
1542 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither AF_INET nor AF_INET6");
1547 if (Z_BVAL_P(return_value
)) {
1548 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_NINFO
, ares
, cb
);
1549 php_ares_query_rsrc(query
, return_value
);
1550 php_ares_query_pckt(query
, PHP_ARES_PCKT_NINFO
, flags
, addr
, addr_len
, family
, port
);
1551 ares_getnameinfo(ares
->channel
, sa
, sa_len
, flags
, php_ares_nameinfo_callback_func
, query
);
1558 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1559 Check a query for its result */
1560 static PHP_FUNCTION(ares_result
)
1562 zval
*rsrc
, *zerrno
= NULL
, *zerror
= NULL
;
1563 php_ares_query
*query
;
1565 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|zz", &rsrc
, &zerrno
, &zerror
)) {
1568 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1572 ZVAL_LONG(zerrno
, query
->error
);
1579 switch (query
->error
) {
1585 #ifdef HAVE_OLD_ARES_STRERROR
1587 const char *__err
= ares_strerror(query
->error
, &__tmp
);
1588 ZVAL_STRING(zerror
, estrdup(__err
), 0);
1589 if (__tmp
) ares_free_errmem(__tmp
);
1591 ZVAL_STRING(zerror
, estrdup(ares_strerror(query
->error
)), 0);
1597 switch (query
->type
) {
1598 case PHP_ARES_CB_STD
:
1599 if (query
->result
.std
.arr
) {
1600 RETVAL_ZVAL(query
->result
.std
.arr
, 1, 0);
1601 } else if (query
->result
.std
.len
> 0) {
1602 RETVAL_STRINGL(query
->result
.std
.buf
, query
->result
.std
.len
, 1);
1605 case PHP_ARES_CB_HOST
:
1606 if (query
->result
.host
.h_name
) {
1607 object_init(return_value
);
1608 php_ares_hostent_to_struct(&query
->result
.host
, HASH_OF(return_value
));
1611 case PHP_ARES_CB_NINFO
:
1612 if (query
->result
.ninfo
.node
|| query
->result
.ninfo
.service
) {
1613 object_init(return_value
);
1614 add_property_string(return_value
, "node", query
->result
.ninfo
.node
? query
->result
.ninfo
.node
: "", 1);
1615 add_property_string(return_value
, "service", query
->result
.ninfo
.service
? query
->result
.ninfo
.service
: "", 1);
1624 /* {{{ proto object ares_packet(resource query)
1625 Check a query for its question packet */
1626 static PHP_FUNCTION(ares_packet
)
1629 php_ares_query
*query
;
1631 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1634 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1636 object_init(return_value
);
1637 add_property_long(return_value
, "type", query
->packet
.type
);
1638 add_property_null(return_value
, "search");
1639 add_property_null(return_value
, "query");
1640 add_property_null(return_value
, "send");
1641 add_property_null(return_value
, "gethostbyname");
1642 add_property_null(return_value
, "gethostbyaddr");
1643 add_property_null(return_value
, "getnameinfo");
1644 MAKE_STD_ZVAL(prop
);
1646 switch (query
->packet
.type
) {
1647 case PHP_ARES_PCKT_SEARCH
:
1649 add_property_stringl(prop
, "name", query
->packet
.data
.search
.name
, query
->packet
.data
.search
.name_len
, 1);
1650 add_property_long(prop
, "type", query
->packet
.data
.search
.type
);
1651 add_property_long(prop
, "dnsclass", query
->packet
.data
.search
.dnsclass
);
1652 add_property_zval(return_value
, "search", prop
);
1655 case PHP_ARES_PCKT_QUERY
:
1657 add_property_stringl(prop
, "name", query
->packet
.data
.query
.name
, query
->packet
.data
.query
.name_len
, 1);
1658 add_property_long(prop
, "type", query
->packet
.data
.query
.type
);
1659 add_property_long(prop
, "dnsclass", query
->packet
.data
.query
.dnsclass
);
1660 add_property_zval(return_value
, "query", prop
);
1663 case PHP_ARES_PCKT_SEND
:
1664 ZVAL_STRINGL(prop
, query
->packet
.data
.send
.buf
, query
->packet
.data
.send
.len
, 1);
1665 add_property_zval(return_value
, "send", prop
);
1668 case PHP_ARES_PCKT_HNAME
:
1670 add_property_stringl(prop
, "name", query
->packet
.data
.hname
.name
, query
->packet
.data
.hname
.name_len
, 1);
1671 add_property_long(prop
, "family", query
->packet
.data
.hname
.family
);
1672 add_property_zval(return_value
, "gethostbyname", prop
);
1675 case PHP_ARES_PCKT_HADDR
:
1677 add_property_stringl(prop
, "addr", query
->packet
.data
.haddr
.addr
, query
->packet
.data
.haddr
.addr_len
, 1);
1678 add_property_long(prop
, "family", query
->packet
.data
.haddr
.family
);
1679 add_property_zval(return_value
, "gethostbyaddr", prop
);
1682 case PHP_ARES_PCKT_NINFO
:
1684 add_property_long(prop
, "flags", query
->packet
.data
.ninfo
.flags
);
1685 add_property_stringl(prop
, "addr", query
->packet
.data
.ninfo
.addr
, query
->packet
.data
.ninfo
.addr_len
, 1);
1686 add_property_long(prop
, "family", query
->packet
.data
.ninfo
.family
);
1687 add_property_long(prop
, "port", query
->packet
.data
.ninfo
.port
);
1688 add_property_zval(return_value
, "getnameinfo", prop
);
1692 zval_ptr_dtor(&prop
);
1696 #ifdef HAVE_ARES_CANCEL
1697 /* {{{ proto void ares_cancel(resource ares)
1698 Cancel pending queries */
1699 static PHP_FUNCTION(ares_cancel
)
1704 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1705 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1706 ares_cancel(ares
->channel
);
1712 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1713 Process all pending queries */
1714 static PHP_FUNCTION(ares_process_all
)
1718 long max_timeout
= -1;
1720 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1723 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1725 while (php_ares_process(ares
, max_timeout
));
1729 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1730 Process once and return whether it should be called again */
1731 static PHP_FUNCTION(ares_process_once
)
1735 long max_timeout
= -1;
1737 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1740 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1742 RETVAL_BOOL(php_ares_process(ares
, max_timeout
));
1746 /* {{{ proto void ares_process(resource ares, array read, array write)
1748 static PHP_FUNCTION(ares_process
)
1750 zval
*rsrc
, *read
= NULL
, *write
= NULL
;
1754 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|a!a!", &rsrc
, &read
, &write
)) {
1757 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1762 php_ares_extract_fds(read
, write
, &R
, &W
, NULL TSRMLS_CC
);
1763 ares_process(ares
->channel
, &R
, &W
);
1767 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1769 static PHP_FUNCTION(ares_select
)
1771 zval
*read
= NULL
, *write
= NULL
;
1776 HashTable resource_map
;
1778 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "aal", &read
, &write
, &timeout
)) {
1783 tv
.tv_sec
= timeout
/ 1000;
1784 tv
.tv_usec
= timeout
% (timeout
* 1000);
1793 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);
1794 nfds
= php_ares_extract_fds(read
, write
, &R
, &W
, &resource_map TSRMLS_CC
);
1795 if (-1 < select(nfds
, &R
, &W
, NULL
, &tv
)) {
1796 zend_hash_clean(Z_ARRVAL_P(read
));
1797 zend_hash_clean(Z_ARRVAL_P(write
));
1798 php_ares_publish_fds(&R
, &W
, read
, write
, &resource_map
);
1803 zend_hash_destroy(&resource_map
);
1807 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1808 Get suggested select timeout in ms */
1809 static PHP_FUNCTION(ares_timeout
)
1812 long max_timeout
= -1;
1813 struct timeval tv
, *tvptr
;
1816 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1819 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1821 if ((tvptr
= php_ares_timeout(ares
, max_timeout
, &tv
))) {
1822 RETURN_LONG(tvptr
->tv_sec
* 1000 + tvptr
->tv_usec
/ 1000);
1828 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1829 Get file descriptors */
1830 static PHP_FUNCTION(ares_fds
)
1832 zval
*rsrc
, *read
, *write
;
1836 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rzz", &rsrc
, &read
, &write
)) {
1839 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1848 ares_fds(ares
->channel
, &R
, &W
);
1849 RETVAL_LONG(php_ares_publish_fds(&R
, &W
, read
, write
, NULL
));
1853 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor
)
1855 php_ares
*ares
= (php_ares
*) rsrc
->ptr
;
1857 ares_destroy(ares
->channel
);
1858 zend_llist_destroy(&ares
->queries
);
1859 php_ares_options_dtor(&ares
->options
);
1863 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor
)
1865 php_ares_query
*query
= (php_ares_query
*) rsrc
->ptr
;
1867 php_ares_query_dtor(query
);
1871 /* {{{ PHP_MINIT_FUNCTION */
1872 static PHP_MINIT_FUNCTION(ares
)
1874 #ifdef HAVE_ARES_LIBRARY_INIT
1875 if (ARES_SUCCESS
!= ares_library_init(ARES_LIB_INIT_ALL
)) {
1879 #ifdef HAVE_ARES_VERSION
1881 int ares_version_num
;
1882 ares_version(&ares_version_num
);
1884 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num
, CONST_PERSISTENT
|CONST_CS
);
1888 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS
, CONST_PERSISTENT
|CONST_CS
);
1889 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA
, CONST_PERSISTENT
|CONST_CS
);
1890 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR
, CONST_PERSISTENT
|CONST_CS
);
1891 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL
, CONST_PERSISTENT
|CONST_CS
);
1892 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND
, CONST_PERSISTENT
|CONST_CS
);
1893 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP
, CONST_PERSISTENT
|CONST_CS
);
1894 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1895 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY
, CONST_PERSISTENT
|CONST_CS
);
1896 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME
, CONST_PERSISTENT
|CONST_CS
);
1897 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY
, CONST_PERSISTENT
|CONST_CS
);
1898 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP
, CONST_PERSISTENT
|CONST_CS
);
1899 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1900 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT
, CONST_PERSISTENT
|CONST_CS
);
1901 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF
, CONST_PERSISTENT
|CONST_CS
);
1902 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE
, CONST_PERSISTENT
|CONST_CS
);
1903 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM
, CONST_PERSISTENT
|CONST_CS
);
1904 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION
, CONST_PERSISTENT
|CONST_CS
);
1906 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR
, CONST_PERSISTENT
|CONST_CS
);
1908 #ifdef ARES_EBADFLAGS
1909 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS
, CONST_PERSISTENT
|CONST_CS
);
1912 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME
, CONST_PERSISTENT
|CONST_CS
);
1914 #ifdef ARES_EBADHINTS
1915 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS
, CONST_PERSISTENT
|CONST_CS
);
1917 #ifdef ARES_ENOTINITIALIZED
1918 REGISTER_LONG_CONSTANT("ARES_ENOTINITIALIZED", ARES_ENOTINITIALIZED
, CONST_PERSISTENT
|CONST_CS
);
1920 #ifdef ARES_ELOADIPHLPAPI
1921 REGISTER_LONG_CONSTANT("ARES_ELOADIPHLPAPI", ARES_ELOADIPHLPAPI
, CONST_PERSISTENT
|CONST_CS
);
1923 #ifdef ARES_EADDRGETNETWORKPARAMS
1924 REGISTER_LONG_CONSTANT("ARES_EADDRGETNETWORKPARAMS", ARES_EADDRGETNETWORKPARAMS
, CONST_PERSISTENT
|CONST_CS
);
1926 #ifdef ARES_ECANCELLED
1927 REGISTER_LONG_CONSTANT("ARES_ECANCELLED", ARES_ECANCELLED
, CONST_PERSISTENT
|CONST_CS
);
1930 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC
, CONST_PERSISTENT
|CONST_CS
);
1931 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY
, CONST_PERSISTENT
|CONST_CS
);
1932 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC
, CONST_PERSISTENT
|CONST_CS
);
1933 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE
, CONST_PERSISTENT
|CONST_CS
);
1934 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN
, CONST_PERSISTENT
|CONST_CS
);
1935 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH
, CONST_PERSISTENT
|CONST_CS
);
1936 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES
, CONST_PERSISTENT
|CONST_CS
);
1937 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP
, CONST_PERSISTENT
|CONST_CS
);
1938 #ifdef ARES_FLAG_EDNS
1939 REGISTER_LONG_CONSTANT("ARES_FLAG_EDNS", ARES_FLAG_EDNS
, CONST_PERSISTENT
|CONST_CS
);
1943 * Address Family Constants
1945 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET
, CONST_PERSISTENT
|CONST_CS
);
1946 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6
, CONST_PERSISTENT
|CONST_CS
);
1949 * Name Info constants
1951 #ifdef ARES_NI_NOFQDN
1952 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN
, CONST_PERSISTENT
|CONST_CS
);
1954 #ifdef ARES_NI_NUMERICHOST
1955 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
1957 #ifdef ARES_NI_NAMEREQD
1958 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD
, CONST_PERSISTENT
|CONST_CS
);
1960 #ifdef ARES_NI_NUMERICSERV
1961 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
1963 #ifdef ARES_NI_DGRAM
1964 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM
, CONST_PERSISTENT
|CONST_CS
);
1967 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP
, CONST_PERSISTENT
|CONST_CS
);
1970 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP
, CONST_PERSISTENT
|CONST_CS
);
1973 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP
, CONST_PERSISTENT
|CONST_CS
);
1976 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP
, CONST_PERSISTENT
|CONST_CS
);
1978 #ifdef ARES_NI_NUMERICSCOPE
1979 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE
, CONST_PERSISTENT
|CONST_CS
);
1981 #ifdef ARES_NI_LOOKUPHOST
1982 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST
, CONST_PERSISTENT
|CONST_CS
);
1984 #ifdef ARES_NI_LOOKUPSERVICE
1985 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE
, CONST_PERSISTENT
|CONST_CS
);
1988 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN
, CONST_PERSISTENT
|CONST_CS
);
1990 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1991 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
1993 #ifdef ARES_NI_IDN_USE_STD
1994 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
1998 * Address Info constants
2000 #ifdef ARES_AI_CANONNAME
2001 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME
, CONST_PERSISTENT
|CONST_CS
);
2003 #ifdef ARES_AI_NUMERICHOST
2004 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
2006 #ifdef ARES_AI_PASSIVE
2007 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE
, CONST_PERSISTENT
|CONST_CS
);
2009 #ifdef ARES_AI_NUMERICSERV
2010 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
2013 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V
, CONST_PERSISTENT
|CONST_CS
);
2016 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL
, CONST_PERSISTENT
|CONST_CS
);
2018 #ifdef ARES_AI_ADDRCONFIG
2019 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG
, CONST_PERSISTENT
|CONST_CS
);
2022 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN
, CONST_PERSISTENT
|CONST_CS
);
2024 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
2025 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
2027 #ifdef ARES_AI_IDN_USE_STD
2028 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
2030 #ifdef ARES_AI_CANONIDN
2031 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN
, CONST_PERSISTENT
|CONST_CS
);
2034 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK
, CONST_PERSISTENT
|CONST_CS
);
2036 #ifdef ARES_GETSOCK_MAXNUM
2037 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM
, CONST_PERSISTENT
|CONST_CS
);
2041 * ns_t (type) constants (arpa/nameser.h)
2044 /* (1) Host address. */
2045 REGISTER_LONG_CONSTANT("ARES_T_A", T_A
, CONST_CS
|CONST_PERSISTENT
);
2048 /* (2) Authoritative server. */
2049 REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS
, CONST_CS
|CONST_PERSISTENT
);
2052 /* (3) Mail destination. */
2053 REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD
, CONST_CS
|CONST_PERSISTENT
);
2056 /* (4) Mail forwarder. */
2057 REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF
, CONST_CS
|CONST_PERSISTENT
);
2060 /* (5) Canonical name. */
2061 REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME
, CONST_CS
|CONST_PERSISTENT
);
2064 /* (6) Start of authority zone. */
2065 REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA
, CONST_CS
|CONST_PERSISTENT
);
2068 /* (7) Mailbox domain name. */
2069 REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB
, CONST_CS
|CONST_PERSISTENT
);
2072 /* (8) Mail group member. */
2073 REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG
, CONST_CS
|CONST_PERSISTENT
);
2076 /* (9) Mail rename name. */
2077 REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR
, CONST_CS
|CONST_PERSISTENT
);
2080 /* (10) Null resource record. */
2081 REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL
, CONST_CS
|CONST_PERSISTENT
);
2084 /* (11) Well known service. */
2085 REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS
, CONST_CS
|CONST_PERSISTENT
);
2088 /* (12) Domain name pointer. */
2089 REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR
, CONST_CS
|CONST_PERSISTENT
);
2092 /* (13) Host information. */
2093 REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO
, CONST_CS
|CONST_PERSISTENT
);
2096 /* (14) Mailbox information. */
2097 REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO
, CONST_CS
|CONST_PERSISTENT
);
2100 /* (15) Mail routing information. */
2101 REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX
, CONST_CS
|CONST_PERSISTENT
);
2104 /* (16) Text strings. */
2105 REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT
, CONST_CS
|CONST_PERSISTENT
);
2108 /* (17) Responsible person. */
2109 REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP
, CONST_CS
|CONST_PERSISTENT
);
2112 /* (18) AFS cell database. */
2113 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB
, CONST_CS
|CONST_PERSISTENT
);
2116 /* (19) X_25 calling address. */
2117 REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25
, CONST_CS
|CONST_PERSISTENT
);
2120 /* (20) ISDN calling address. */
2121 REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN
, CONST_CS
|CONST_PERSISTENT
);
2125 REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT
, CONST_CS
|CONST_PERSISTENT
);
2128 /* (22) NSAP address. */
2129 REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP
, CONST_CS
|CONST_PERSISTENT
);
2132 /* (23) Reverse NSAP lookup (deprecated). */
2133 REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR
, CONST_CS
|CONST_PERSISTENT
);
2136 /* (24) Security signature. */
2137 REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG
, CONST_CS
|CONST_PERSISTENT
);
2140 /* (25) Security key. */
2141 REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY
, CONST_CS
|CONST_PERSISTENT
);
2144 /* (26) X.400 mail mapping. */
2145 REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX
, CONST_CS
|CONST_PERSISTENT
);
2148 /* (27) Geographical position (withdrawn). */
2149 REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS
, CONST_CS
|CONST_PERSISTENT
);
2152 /* (28) Ip6 Address. */
2153 REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA
, CONST_CS
|CONST_PERSISTENT
);
2156 /* (29) Location Information. */
2157 REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC
, CONST_CS
|CONST_PERSISTENT
);
2160 /* (30) Next domain (security). */
2161 REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT
, CONST_CS
|CONST_PERSISTENT
);
2164 /* (31) Endpoint identifier. */
2165 REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID
, CONST_CS
|CONST_PERSISTENT
);
2168 /* (32) Nimrod Locator. */
2169 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC
, CONST_CS
|CONST_PERSISTENT
);
2172 /* (33) Server Selection. */
2173 REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV
, CONST_CS
|CONST_PERSISTENT
);
2176 /* (34) ATM Address */
2177 REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA
, CONST_CS
|CONST_PERSISTENT
);
2180 /* (35) Naming Authority Pointer */
2181 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR
, CONST_CS
|CONST_PERSISTENT
);
2184 /* (36) Key Exchange */
2185 REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX
, CONST_CS
|CONST_PERSISTENT
);
2188 /* (37) Certification record */
2189 REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT
, CONST_CS
|CONST_PERSISTENT
);
2192 /* (38) IPv6 address (deprecates AAAA) */
2193 REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6
, CONST_CS
|CONST_PERSISTENT
);
2196 /* (39) Non-terminal DNAME (for IPv6) */
2197 REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME
, CONST_CS
|CONST_PERSISTENT
);
2200 /* (40) Kitchen sink (experimentatl) */
2201 REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK
, CONST_CS
|CONST_PERSISTENT
);
2204 /* (41) EDNS0 option (meta-RR) */
2205 REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT
, CONST_CS
|CONST_PERSISTENT
);
2208 /* (250) Transaction signature. */
2209 REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG
, CONST_CS
|CONST_PERSISTENT
);
2212 /* (251) Incremental zone transfer. */
2213 REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR
, CONST_CS
|CONST_PERSISTENT
);
2216 /* (252) Transfer zone of authority. */
2217 REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR
, CONST_CS
|CONST_PERSISTENT
);
2220 /* (253) Transfer mailbox records. */
2221 REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB
, CONST_CS
|CONST_PERSISTENT
);
2224 /* (254) Transfer mail agent records. */
2225 REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA
, CONST_CS
|CONST_PERSISTENT
);
2228 /* (255) Wildcard match. */
2229 REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY
, CONST_CS
|CONST_PERSISTENT
);
2233 * ns_c (dnsclass) constants (arpa/nameser.h)
2238 REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN
, CONST_CS
|CONST_PERSISTENT
);
2241 /* (2) unallocated/unsupported. */
2242 REGISTER_LONG_CONSTANT("ARES_C_2", C_2
, CONST_CS
|CONST_PERSISTENT
);
2245 /* (3) MIT Chaos-net. */
2246 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS
, CONST_CS
|CONST_PERSISTENT
);
2249 /* (4) MIT Hesiod. */
2250 REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS
, CONST_CS
|CONST_PERSISTENT
);
2253 /* (254) for prereq. sections in update requests */
2254 REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE
, CONST_CS
|CONST_PERSISTENT
);
2257 /* (255) Wildcard match. */
2258 REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY
, CONST_CS
|CONST_PERSISTENT
);
2261 le_ares
= zend_register_list_destructors_ex(php_ares_le_dtor
, NULL
, PHP_ARES_LE_NAME
, module_number
);
2262 le_ares_query
= zend_register_list_destructors_ex(php_ares_query_le_dtor
, NULL
, PHP_ARES_QUERY_LE_NAME
, module_number
);
2268 /* {{{ PHP_MSHUTDOWN_FUNCTION */
2269 static PHP_MSHUTDOWN_FUNCTION(ares
)
2271 #ifdef HAVE_ARES_LIBRARY_CLEANUP
2272 ares_library_cleanup();
2278 /* {{{ PHP_MINFO_FUNCTION */
2279 static PHP_MINFO_FUNCTION(ares
)
2281 php_info_print_table_start();
2282 php_info_print_table_header(2, "AsyncResolver support", "enabled");
2283 php_info_print_table_row(2, "Version", PHP_ARES_VERSION
);
2284 php_info_print_table_end();
2286 php_info_print_table_start();
2287 php_info_print_table_header(3, "Used Library", "compiled", "linked");
2288 php_info_print_table_row(3,
2290 #ifdef ARES_VERSION_STR
2295 #ifdef HAVE_ARES_VERSION
2301 php_info_print_table_end();
2305 #ifdef ZEND_ENGINE_2
2306 ZEND_BEGIN_ARG_INFO(ai_ares_select
, 0)
2307 ZEND_ARG_PASS_INFO(1)
2308 ZEND_ARG_PASS_INFO(1)
2309 ZEND_ARG_PASS_INFO(0)
2310 ZEND_END_ARG_INFO();
2312 ZEND_BEGIN_ARG_INFO(ai_ares_result
, 0)
2313 ZEND_ARG_PASS_INFO(0)
2314 ZEND_ARG_PASS_INFO(1)
2315 ZEND_ARG_PASS_INFO(1)
2316 ZEND_END_ARG_INFO();
2318 ZEND_BEGIN_ARG_INFO(ai_ares_fds
, 0)
2319 ZEND_ARG_PASS_INFO(0)
2320 ZEND_ARG_PASS_INFO(1)
2321 ZEND_ARG_PASS_INFO(1)
2322 ZEND_END_ARG_INFO();
2324 static unsigned char ai_ares_select
[] = {3, BYREF_FORCE
, BYREF_FORCE
, BYREF_NONE
};
2325 static unsigned char ai_ares_result
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
2326 static unsigned char ai_ares_fds
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
2329 /* {{{ ares_functions[] */
2330 zend_function_entry ares_functions
[] = {
2331 #ifdef HAVE_ARES_VERSION
2332 PHP_FE(ares_version
, NULL
)
2334 PHP_FE(ares_init
, NULL
)
2335 PHP_FE(ares_destroy
, NULL
)
2336 PHP_FE(ares_strerror
, NULL
)
2337 #ifdef HAVE_ARES_CANCEL
2338 PHP_FE(ares_cancel
, NULL
)
2340 PHP_FE(ares_search
, NULL
)
2341 PHP_FE(ares_query
, NULL
)
2342 PHP_FE(ares_send
, NULL
)
2343 PHP_FE(ares_mkquery
, NULL
)
2344 PHP_FE(ares_gethostbyname
, NULL
)
2345 PHP_FE(ares_gethostbyaddr
, NULL
)
2346 #ifdef HAVE_ARES_GETNAMEINFO
2347 PHP_FE(ares_getnameinfo
, NULL
)
2349 PHP_FE(ares_result
, ai_ares_result
)
2350 PHP_FE(ares_packet
, NULL
)
2351 PHP_FE(ares_process_all
, NULL
)
2352 PHP_FE(ares_process_once
, NULL
)
2353 PHP_FE(ares_process
, NULL
)
2354 PHP_FE(ares_select
, ai_ares_select
)
2355 PHP_FE(ares_fds
, ai_ares_fds
)
2356 PHP_FE(ares_timeout
, NULL
)
2357 #ifdef HAVE_ARES_SET_LOCAL_DEV
2358 PHP_FE(ares_set_local_dev
, NULL
)
2360 #ifdef HAVE_ARES_SET_LOCAL_IP4
2361 PHP_FE(ares_set_local_ip4
, NULL
)
2363 #ifdef HAVE_ARES_SET_LOCAL_IP6
2364 PHP_FE(ares_set_local_ip6
, NULL
)
2370 /* {{{ ares_module_entry */
2371 zend_module_entry ares_module_entry
= {
2372 STANDARD_MODULE_HEADER
,
2376 PHP_MSHUTDOWN(ares
),
2381 STANDARD_MODULE_PROPERTIES
2385 #ifdef COMPILE_DL_ARES
2386 ZEND_GET_MODULE(ares
)
2394 * vim600: noet sw=4 ts=4 fdm=marker
2395 * vim<600: noet sw=4 ts=4