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 "ext/standard/info.h"
25 #ifdef HAVE_ARES_VERSION
26 # include <ares_version.h>
34 #ifdef HAVE_ARPA_INET_H
35 # include <arpa/inet.h>
37 #ifdef HAVE_ARPA_NAMESER_H
38 # include <arpa/nameser.h>
40 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
41 # include <arpa/nameser_compat.h>
44 #define local static inline
47 # define PHP_ARES_IS_CALLABLE(a,b,c) 1
49 # undef TSRMLS_SET_CTX
50 # define TSRMLS_SET_CTX
51 # undef TSRMLS_FETCH_FROM_CTX
52 # define TSRMLS_FETCH_FROM_CTX
55 #if (PHP_MAJOR_VERSION > 5) || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3))
56 # define ADDREF(z) Z_ADDREF_P(z)
57 # define PHP_ARES_IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c) TSRMLS_CC)
59 # define ADDREF(z) ZVAL_ADDREF(z)
60 # define PHP_ARES_IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
63 #define PHP_ARES_LE_NAME "AsyncResolver"
64 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
66 static int le_ares_query
;
68 static const char *php_ares_C_names
[] = {
77 static const char *php_ares_T_names
[] = {
121 "","","","","","","","","","","","","","","","","","","","", /* 20x */
122 "","","","","","","","","","","","","","","","","","","","", /* 20x */
123 "","","","","","","","","","","","","","","","","","","","", /* 20x */
124 "","","","","","","","","","","","","","","","","","","","", /* 20x */
125 "","","","","","","","","","","","","","","","","","","","", /* 20x */
126 "","","","","","","","","","","","","","","","","","","","", /* 20x */
127 "","","","","","","","","","","","","","","","","","","","", /* 20x */
128 "","","","","","","","","","","","","","","","","","","","", /* 20x */
129 "","","","","","","","","","","","","","","","","","","","", /* 20x */
130 "","","","","","","","","","","","","","","","","","","","", /* 20x */
131 "","","","","","","","","","","","","","","","","","","","", /* 20x */
132 "","","","","","","","","","","","","","","","","","","","", /* 20x */
133 "","","","","","", /* 6x */
144 #ifdef HAVE_OLD_ARES_STRERROR
145 # define PHP_ARES_ERROR(err) { \
146 char *__tmp = NULL; \
147 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err, &__tmp)); \
148 if (__tmp) ares_free_errmem(__tmp); \
151 # define PHP_ARES_ERROR(err) \
152 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
155 #define RETURN_ARES_ERROR(err) \
156 PHP_ARES_ERROR(err); \
158 #define PHP_ARES_CB_ERROR(param) \
159 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected the " param " argument to be a valid callback")
160 #define RETURN_ARES_CB_ERROR(param) \
161 PHP_ARES_CB_ERROR(param); \
164 #define PHP_ARES_QUERY_BUFFER_LEN 2<<0xf
167 typedef struct _php_ares_options
{
168 struct ares_options strct
;
172 typedef struct _php_ares
{
173 ares_channel channel
;
174 php_ares_options options
;
177 unsigned in_callback
:1;
178 unsigned reserved
:31;
181 typedef enum _php_ares_query_type
{
185 } php_ares_query_type
;
187 typedef enum _php_ares_query_packet_type
{
188 PHP_ARES_PCKT_SEARCH
,
194 } php_ares_query_packet_type
;
196 typedef union _php_ares_query_packet_data
{
230 } php_ares_query_packet_data
;
232 typedef struct _php_ares_query_packet
{
233 php_ares_query_packet_type type
;
234 php_ares_query_packet_data data
;
235 } php_ares_query_packet
;
237 typedef union _php_ares_query_result
{
248 } php_ares_query_result
;
250 typedef struct _php_ares_query
{
255 php_ares_query_type type
;
256 php_ares_query_packet packet
;
257 php_ares_query_result result
;
261 local
struct hostent
*php_ares_hostent_ctor(struct hostent
*host
) /* {{{ */
264 host
= emalloc(sizeof(struct hostent
));
266 memset(host
, 0, sizeof(struct hostent
));
272 local
void php_ares_hostent_copy(struct hostent
*from
, struct hostent
*to
) /* {{{ */
277 memcpy(to
, from
, sizeof(struct hostent
));
278 to
->h_name
= estrdup(from
->h_name
);
279 for (c
= 0, ptr
= from
->h_aliases
; *ptr
; ++ptr
, ++c
);
280 to
->h_aliases
= ecalloc((c
+1), sizeof(char *));
281 for (i
= 0; i
< c
; ++i
) {
282 to
->h_aliases
[i
] = estrdup(from
->h_aliases
[i
]);
284 for (c
= 0, ptr
= from
->h_addr_list
; *ptr
; ++ptr
, ++c
);
285 to
->h_addr_list
= ecalloc((c
+1), sizeof(char *));
286 for (i
= 0; i
< c
; ++i
) {
287 to
->h_addr_list
[i
] = emalloc(from
->h_length
);
288 memcpy(to
->h_addr_list
[i
], from
->h_addr_list
[i
], from
->h_length
);
293 local
void php_ares_hostent_to_struct(struct hostent
*hostent
, HashTable
*ht
) /* {{{ */
299 Z_TYPE(array
) = IS_ARRAY
;
300 Z_ARRVAL(array
) = ht
;
303 add_assoc_string(&array
, "name", hostent
->h_name
, 1);
307 if (hostent
->h_aliases
) {
308 for (ptr
= hostent
->h_aliases
; *ptr
; ++ptr
) {
309 add_next_index_string(tmp
, *ptr
, 1);
312 add_assoc_zval(&array
, "aliases", tmp
);
313 add_assoc_long(&array
, "addrtype", hostent
->h_addrtype
);
317 if (hostent
->h_addr_list
) {
318 for (ptr
= hostent
->h_addr_list
; *ptr
; ++ptr
) {
321 if (inet_ntop(hostent
->h_addrtype
, *ptr
, name
, sizeof(name
)-1)) {
322 add_next_index_string(tmp
, name
, 1);
326 add_assoc_zval(&array
, "addrlist", tmp
);
331 local
void php_ares_hostent_dtor(struct hostent
*host
) /* {{{ */
335 STR_FREE(host
->h_name
);
336 if (host
->h_aliases
) {
337 for (ptr
= host
->h_aliases
; *ptr
; ++ptr
) {
340 efree(host
->h_aliases
);
342 if (host
->h_addr_list
) {
343 for (ptr
= host
->h_addr_list
; *ptr
; ++ptr
) {
346 efree(host
->h_addr_list
);
348 memset(host
, 0, sizeof(struct hostent
));
352 local
void php_ares_hostent_free(struct hostent
**host
) /* {{{ */
354 php_ares_hostent_dtor(*host
);
360 local php_ares_query
*php_ares_query_ctor(php_ares_query
*query
, php_ares_query_type type
, php_ares
*ares
, zval
*callback
) /* {{{ */
363 query
= emalloc(sizeof(php_ares_query
));
365 memset(query
, 0, sizeof(php_ares_query
));
373 query
->callback
= callback
;
380 local
void php_ares_query_rsrc(php_ares_query
*query
, zval
*return_value
) /* {{{ */
382 TSRMLS_FETCH_FROM_CTX(query
->ares
->tsrm_ls
);
384 ZEND_REGISTER_RESOURCE(return_value
, query
, le_ares_query
);
385 query
->id
= Z_LVAL_P(return_value
);
386 zend_list_addref(query
->id
);
387 zend_llist_add_element(&query
->ares
->queries
, &query
);
391 local
void php_ares_query_pckt(php_ares_query
*query
, php_ares_query_packet_type type
, ...)
397 va_start(argv
, type
);
399 switch (query
->packet
.type
= type
) {
400 case PHP_ARES_PCKT_SEARCH
:
401 buf
= va_arg(argv
, char *);
402 len
= va_arg(argv
, int);
403 query
->packet
.data
.search
.name
= estrndup(buf
, len
);
404 query
->packet
.data
.search
.name_len
= len
;
405 query
->packet
.data
.search
.type
= va_arg(argv
, long);
406 query
->packet
.data
.search
.dnsclass
= va_arg(argv
, long);
409 case PHP_ARES_PCKT_QUERY
:
410 buf
= va_arg(argv
, char *);
411 len
= va_arg(argv
, int);
412 query
->packet
.data
.query
.name
= estrndup(buf
, len
);
413 query
->packet
.data
.query
.name_len
= len
;
414 query
->packet
.data
.query
.type
= va_arg(argv
, long);
415 query
->packet
.data
.query
.dnsclass
= va_arg(argv
, long);
418 case PHP_ARES_PCKT_SEND
:
419 buf
= va_arg(argv
, char *);
420 len
= va_arg(argv
, int);
421 query
->packet
.data
.send
.buf
= estrndup(buf
, len
);
422 query
->packet
.data
.send
.len
= len
;
425 case PHP_ARES_PCKT_HNAME
:
426 buf
= va_arg(argv
, char *);
427 len
= va_arg(argv
, int);
428 query
->packet
.data
.hname
.name
= estrndup(buf
, len
);
429 query
->packet
.data
.hname
.name_len
= len
;
430 query
->packet
.data
.hname
.family
= va_arg(argv
, long);
433 case PHP_ARES_PCKT_HADDR
:
434 buf
= va_arg(argv
, char *);
435 len
= va_arg(argv
, int);
436 query
->packet
.data
.haddr
.addr
= estrndup(buf
, len
);
437 query
->packet
.data
.haddr
.addr_len
= len
;
438 query
->packet
.data
.haddr
.family
= va_arg(argv
, long);
441 case PHP_ARES_PCKT_NINFO
:
442 query
->packet
.data
.ninfo
.flags
= va_arg(argv
, long);
443 buf
= va_arg(argv
, char *);
444 len
= va_arg(argv
, int);
445 query
->packet
.data
.ninfo
.addr
= estrndup(buf
, len
);
446 query
->packet
.data
.ninfo
.addr_len
= len
;
447 query
->packet
.data
.ninfo
.family
= va_arg(argv
, long);
448 query
->packet
.data
.ninfo
.port
= va_arg(argv
, long);
455 local
void php_ares_query_dtor(php_ares_query
*query
) /* {{{ */
457 struct php_ares_query_packet_buf
{char *buf
;} *packet
;
459 packet
= (struct php_ares_query_packet_buf
*) &query
->packet
.data
;
463 switch (query
->type
) {
464 case PHP_ARES_CB_STD
:
465 if (query
->result
.std
.arr
) {
466 zval_ptr_dtor(&query
->result
.std
.arr
);
468 STR_FREE(query
->result
.std
.buf
);
470 case PHP_ARES_CB_HOST
:
471 php_ares_hostent_dtor(&query
->result
.host
);
473 case PHP_ARES_CB_NINFO
:
474 STR_FREE(query
->result
.ninfo
.service
);
475 STR_FREE(query
->result
.ninfo
.node
);
478 if (query
->callback
) {
479 zval_ptr_dtor(&query
->callback
);
481 memset(query
, 0, sizeof(php_ares_query
));
485 local
void php_ares_query_free(php_ares_query
**query
) /* {{{ */
487 php_ares_query_dtor(*query
);
493 local php_ares_options
*php_ares_options_ctor(php_ares_options
*options
, HashTable
*ht
) /* {{{ */
499 options
= emalloc(sizeof(php_ares_options
));
501 memset(options
, 0, sizeof(php_ares_options
));
503 if (ht
&& zend_hash_num_elements(ht
)) {
504 if ((SUCCESS
== zend_hash_find(ht
, "flags", sizeof("flags"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
505 options
->flags
|= ARES_OPT_FLAGS
;
506 options
->strct
.flags
= Z_LVAL_PP(opt
);
508 if ((SUCCESS
== zend_hash_find(ht
, "timeout", sizeof("timeout"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
509 options
->flags
|= ARES_OPT_TIMEOUT
;
510 options
->strct
.timeout
= Z_LVAL_PP(opt
);
512 if ((SUCCESS
== zend_hash_find(ht
, "tries", sizeof("tries"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
513 options
->flags
|= ARES_OPT_TRIES
;
514 options
->strct
.tries
= Z_LVAL_PP(opt
);
516 if ((SUCCESS
== zend_hash_find(ht
, "ndots", sizeof("ndots"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
517 options
->flags
|= ARES_OPT_NDOTS
;
518 options
->strct
.ndots
= Z_LVAL_PP(opt
);
520 if ((SUCCESS
== zend_hash_find(ht
, "udp_port", sizeof("udp_port"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
521 options
->flags
|= ARES_OPT_UDP_PORT
;
522 options
->strct
.udp_port
= htons((unsigned short) Z_LVAL_PP(opt
));
524 if ((SUCCESS
== zend_hash_find(ht
, "tcp_port", sizeof("tcp_port"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
525 options
->flags
|= ARES_OPT_TCP_PORT
;
526 options
->strct
.tcp_port
= htons((unsigned short) Z_LVAL_PP(opt
));
528 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
)))) {
529 options
->strct
.servers
= ecalloc(i
, sizeof(struct in_addr
));
530 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt
));
531 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_PP(opt
), (void *) &entry
);
532 zend_hash_move_forward(Z_ARRVAL_PP(opt
))) {
533 if (Z_TYPE_PP(entry
) == IS_STRING
) {
534 inet_aton(Z_STRVAL_PP(entry
), &options
->strct
.servers
[options
->strct
.nservers
++]);
537 if (options
->strct
.nservers
) {
538 options
->flags
|= ARES_OPT_SERVERS
;
541 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
)))) {
542 options
->strct
.domains
= ecalloc(i
, sizeof(char *));
543 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt
));
544 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_PP(opt
), (void *) &entry
);
545 zend_hash_move_forward(Z_ARRVAL_PP(opt
))) {
546 if (Z_TYPE_PP(entry
) == IS_STRING
) {
547 options
->strct
.domains
[options
->strct
.ndomains
++] = estrdup(Z_STRVAL_PP(entry
));
550 if (options
->strct
.ndomains
) {
551 options
->flags
|= ARES_OPT_DOMAINS
;
554 if ((SUCCESS
== zend_hash_find(ht
, "lookups", sizeof("lookups"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_STRING
)) {
555 options
->flags
|= ARES_OPT_LOOKUPS
;
556 options
->strct
.lookups
= estrdup(Z_STRVAL_PP(opt
));
564 local
void php_ares_options_dtor(php_ares_options
*options
) /* {{{ */
568 if (options
->strct
.servers
) {
569 efree(options
->strct
.servers
);
572 if (options
->strct
.domains
) {
573 for (i
= 0; i
< options
->strct
.ndomains
; ++i
) {
574 efree(options
->strct
.domains
[i
]);
576 efree(options
->strct
.domains
);
579 STR_FREE(options
->strct
.lookups
);
581 memset(options
, 0, sizeof(php_ares_options
));
585 local
void php_ares_options_free(php_ares_options
**options
) /* {{{ */
587 php_ares_options_dtor(*options
);
593 local PHP_ARES_EXPAND_LEN_TYPE
php_ares_skip(const unsigned char *pointer
, const unsigned char *abuf
, int alen TSRMLS_DC
)
597 PHP_ARES_EXPAND_LEN_TYPE byte_count
;
599 /* NOTE: byte_count is not neccessarily the length of the string,
600 i.e. if there were back references */
601 if (ARES_SUCCESS
== (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
602 /*fprintf(stderr, "-- skipping %s\n", name);*/
603 ares_free_string(name
);
610 local
int php_ares_parse(const unsigned char *abuf
, int alen
, zval
*result TSRMLS_DC
) /* {{{ */
613 PHP_ARES_EXPAND_LEN_TYPE byte_count
;
614 const unsigned char *pointer
;
616 int rc
, query_count
, answer_count
;
618 convert_to_array(result
);
620 if (!alen
|| !abuf
|| !*abuf
) {
624 header
= (HEADER
*) abuf
;
625 pointer
= abuf
+ HFIXEDSZ
;
627 for (query_count
= ntohs(header
->qdcount
); query_count
--; pointer
+= byte_count
+ QFIXEDSZ
) {
628 if (0 > (byte_count
= php_ares_skip(pointer
, abuf
, alen TSRMLS_CC
))) {
633 for (answer_count
= ntohs(header
->ancount
); answer_count
-- && pointer
< (abuf
+ alen
); ) {
634 uint16_t stmp
, type
, class;
636 zval
**entry_ptr
, *entry
= NULL
;
638 if (0 > (byte_count
= php_ares_skip(pointer
, abuf
, alen TSRMLS_CC
))) {
642 pointer
+= byte_count
;
644 MAKE_STD_ZVAL(entry
);
647 GETSHORT(type
, pointer
);
648 add_assoc_string(entry
, "type", estrdup(php_ares_T_names
[type
]), 0);
649 GETSHORT(class, pointer
);
650 add_assoc_string(entry
, "class", estrdup(php_ares_C_names
[class]), 0);
651 GETLONG(ttl
, pointer
);
652 add_assoc_long(entry
, "ttl", ttl
);
653 GETSHORT(byte_count
, pointer
);
655 fprintf(stderr
, ">> processing %s answer of length %d\n", php_ares_T_names
[type
], byte_count
);
659 spprintf(&name
, 0, "%d.%d.%d.%d", pointer
[0], pointer
[1], pointer
[2], pointer
[3]);
660 add_assoc_string(entry
, "addr", name
, 0);
661 pointer
+= byte_count
;
667 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
671 pointer
+= byte_count
;
672 add_assoc_string(entry
, "name", name
, 1);
673 ares_free_string(name
);
677 GETSHORT(stmp
, pointer
);
678 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
682 pointer
+= byte_count
;
683 add_assoc_long(entry
, "weight", stmp
);
684 add_assoc_string(entry
, "name", name
, 1);
685 ares_free_string(name
);
689 GETSHORT(stmp
, pointer
);
690 add_assoc_long(entry
, "priority", stmp
);
691 GETSHORT(stmp
, pointer
);
692 add_assoc_long(entry
, "weight", stmp
);
693 GETSHORT(stmp
, pointer
);
694 add_assoc_long(entry
, "port", stmp
);
696 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
698 zval_ptr_dtor(&entry
);
701 pointer
+= byte_count
;
702 add_assoc_string(entry
, "name", name
, 1);
703 ares_free_string(name
);
707 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
709 zval_ptr_dtor(&entry
);
712 pointer
+= byte_count
;
713 add_assoc_string(entry
, "name", name
, 1);
714 ares_free_string(name
);
716 if (ARES_SUCCESS
!= (rc
= ares_expand_name(pointer
, abuf
, alen
, &name
, &byte_count
))) {
718 zval_ptr_dtor(&entry
);
721 pointer
+= byte_count
;
722 add_assoc_string(entry
, "mail", name
, 1);
723 ares_free_string(name
);
725 GETLONG(ltmp
, pointer
);
726 add_assoc_long(entry
, "serial", ltmp
);
727 GETLONG(ltmp
, pointer
);
728 add_assoc_long(entry
, "refresh", ltmp
);
729 GETLONG(ltmp
, pointer
);
730 add_assoc_long(entry
, "retry", ltmp
);
731 GETLONG(ltmp
, pointer
);
732 add_assoc_long(entry
, "expire", ltmp
);
733 GETLONG(ltmp
, pointer
);
734 add_assoc_long(entry
, "minimum-ttl", ltmp
);
738 for (ltmp
= 0; ltmp
< byte_count
; ltmp
+= pointer
[ltmp
] + 1) {
739 add_next_index_stringl(entry
, (const char *) &pointer
[ltmp
+ 1], pointer
[ltmp
], 1);
741 pointer
+= byte_count
;
745 zval_ptr_dtor(&entry
);
747 pointer
+= byte_count
;
752 add_next_index_zval(result
, entry
);
761 static void php_ares_callback_func_old(void *aq
, int status
, unsigned char *abuf
, int alen
)
763 php_ares_query
*q
= (php_ares_query
*) aq
;
764 zval
*params
[4], *retval
, *parsed
= NULL
;
765 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
769 q
->result
.std
.buf
= estrndup((char *) abuf
, alen
);
770 q
->result
.std
.len
= alen
;
772 MAKE_STD_ZVAL(parsed
);
774 if (SUCCESS
== php_ares_parse(abuf
, alen
, parsed
)) {
775 q
->result
.std
.arr
= parsed
;
777 zval_ptr_dtor(&parsed
);
783 MAKE_STD_ZVAL(retval
);
784 MAKE_STD_ZVAL(params
[0]);
785 MAKE_STD_ZVAL(params
[1]);
786 MAKE_STD_ZVAL(params
[2]);
788 zend_list_addref(q
->id
);
789 Z_LVAL_P(params
[0]) = q
->id
;
790 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
791 ZVAL_LONG(params
[1], status
);
792 ZVAL_STRINGL(params
[2], (char *) abuf
, alen
, 1);
799 q
->ares
->in_callback
= 1;
800 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, parsed
? 4 : 3, params TSRMLS_CC
);
801 q
->ares
->in_callback
= 0;
803 zval_ptr_dtor(&retval
);
804 zval_ptr_dtor(¶ms
[0]);
805 zval_ptr_dtor(¶ms
[1]);
806 zval_ptr_dtor(¶ms
[2]);
809 zval_ptr_dtor(¶ms
[3]);
814 static void php_ares_host_callback_func_old(void *aq
, int status
, struct hostent
*hostent
)
816 php_ares_query
*q
= (php_ares_query
*) aq
;
817 zval
*params
[3], *retval
;
818 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
822 php_ares_hostent_copy(hostent
, &q
->result
.host
);
826 MAKE_STD_ZVAL(retval
);
827 MAKE_STD_ZVAL(params
[0]);
828 MAKE_STD_ZVAL(params
[1]);
829 MAKE_STD_ZVAL(params
[2]);
831 zend_list_addref(q
->id
);
832 Z_LVAL_P(params
[0]) = q
->id
;
833 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
834 ZVAL_LONG(params
[1], status
);
835 object_init(params
[2]);
836 php_ares_hostent_to_struct(hostent
, HASH_OF(params
[2]));
838 q
->ares
->in_callback
= 1;
839 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 3, params TSRMLS_CC
);
840 q
->ares
->in_callback
= 0;
842 zval_ptr_dtor(&retval
);
843 zval_ptr_dtor(¶ms
[0]);
844 zval_ptr_dtor(¶ms
[1]);
845 zval_ptr_dtor(¶ms
[2]);
849 #ifdef HAVE_ARES_GETNAMEINFO
850 static void php_ares_nameinfo_callback_func_old(void *aq
, int status
, char *node
, char *service
)
852 php_ares_query
*q
= (php_ares_query
*) aq
;
853 zval
*params
[4], *retval
;
854 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
858 q
->result
.ninfo
.node
= estrdup(node
);
861 q
->result
.ninfo
.service
= estrdup(service
);
865 MAKE_STD_ZVAL(retval
);
866 MAKE_STD_ZVAL(params
[0]);
867 MAKE_STD_ZVAL(params
[1]);
868 MAKE_STD_ZVAL(params
[2]);
869 MAKE_STD_ZVAL(params
[3]);
871 zend_list_addref(q
->id
);
872 Z_LVAL_P(params
[0]) = q
->id
;
873 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
874 ZVAL_LONG(params
[1], status
);
876 ZVAL_STRING(params
[2], node
, 1);
878 ZVAL_NULL(params
[2]);
881 ZVAL_STRING(params
[3], service
, 1);
883 ZVAL_NULL(params
[3]);
886 q
->ares
->in_callback
= 1;
887 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 4, params TSRMLS_CC
);
888 q
->ares
->in_callback
= 0;
890 zval_ptr_dtor(&retval
);
891 zval_ptr_dtor(¶ms
[0]);
892 zval_ptr_dtor(¶ms
[1]);
893 zval_ptr_dtor(¶ms
[2]);
894 zval_ptr_dtor(¶ms
[3]);
899 #if PHP_ARES_NEW_CALLBACK_API
900 # define php_ares_callback_func php_ares_callback_func_new
901 static void php_ares_callback_func_new(void *aq
, int status
, int timeouts
, unsigned char *abuf
, int alen
)
903 php_ares_callback_func_old(aq
, status
, abuf
, alen
);
906 # define php_ares_host_callback_func php_ares_host_callback_func_new
907 static void php_ares_host_callback_func_new(void *aq
, int status
, int timeouts
, struct hostent
*hostent
)
909 php_ares_host_callback_func_old(aq
, status
, hostent
);
912 # ifdef HAVE_ARES_GETNAMEINFO
913 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
914 static void php_ares_nameinfo_callback_func_new(void *aq
, int status
, int timeouts
, char *node
, char *service
)
916 php_ares_nameinfo_callback_func_old(aq
, status
, node
, service
);
921 # define php_ares_callback_func php_ares_callback_func_old
922 # define php_ares_host_callback_func php_ares_host_callback_func_old
923 # ifdef HAVE_ARES_GETNAMEINFO
924 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
929 local
struct timeval
*php_ares_timeout(php_ares
*ares
, long max_timeout
, struct timeval
*tv_buf
) /* {{{ */
931 struct timeval maxtv
;
933 if (max_timeout
> -1) {
934 maxtv
.tv_sec
= max_timeout
/ 1000;
935 maxtv
.tv_usec
= max_timeout
% (max_timeout
* 1000);
938 return ares_timeout(ares
->channel
, max_timeout
> -1 ? &maxtv
: NULL
, tv_buf
);
942 local
int php_ares_process(php_ares
*ares
, long max_timeout
) /* {{{ */
951 if ((nfds
= ares_fds(ares
->channel
, &R
, &W
))) {
952 if (0 < select(nfds
, &R
, &W
, NULL
, php_ares_timeout(ares
, max_timeout
, &tv
))) {
953 ares_process(ares
->channel
, &R
, &W
);
961 local
int php_ares_publish_fds(fd_set
*R
, fd_set
*W
, zval
*r
, zval
*w
) /* {{{ */
965 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
966 if (FD_ISSET(i
, R
)) {
967 add_next_index_long(r
, i
);
974 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
975 if (FD_ISSET(i
, W
)) {
976 add_next_index_long(w
, i
);
983 return nfds
? nfds
+ 1 : 0;
987 local
int php_ares_extract_fds(zval
*r
, zval
*w
, fd_set
*R
, fd_set
*W
) /* {{{ */
992 if (r
&& zend_hash_num_elements(Z_ARRVAL_P(r
))) {
993 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r
));
994 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(r
), (void *) &fd
);
995 zend_hash_move_forward(Z_ARRVAL_P(r
))) {
996 if (Z_TYPE_PP(fd
) == IS_LONG
) {
997 FD_SET(Z_LVAL_PP(fd
), R
);
998 if (Z_LVAL_PP(fd
) > nfds
) {
999 nfds
= Z_LVAL_PP(fd
);
1005 if (w
&& zend_hash_num_elements(Z_ARRVAL_P(w
))) {
1006 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w
));
1007 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(w
), (void *) &fd
);
1008 zend_hash_move_forward(Z_ARRVAL_P(w
))) {
1009 if (Z_TYPE_PP(fd
) == IS_LONG
) {
1010 FD_SET(Z_LVAL_PP(fd
), W
);
1011 if (Z_LVAL_PP(fd
) > nfds
) {
1012 nfds
= Z_LVAL_PP(fd
);
1018 return nfds
? nfds
+ 1 : 0;
1022 static void php_ares_query_llist_dtor(void *entry
)
1024 php_ares_query
*q
= *(php_ares_query
**) entry
;
1025 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
1026 zend_list_delete(q
->id
);
1029 #ifdef HAVE_ARES_VERSION
1030 /* {{{ proto string ares_version()
1031 Get libares version */
1032 static PHP_FUNCTION(ares_version
)
1034 if (ZEND_NUM_ARGS()) {
1038 RETURN_STRING(estrdup(ares_version(NULL
)), 0);
1043 /* {{{ proto resource ares_init([array options])
1044 Create an ares resource */
1045 static PHP_FUNCTION(ares_init
)
1047 zval
*opt_array
= NULL
;
1048 php_ares
*ares
= NULL
;
1051 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a!", &opt_array
)) {
1055 ares
= emalloc(sizeof(php_ares
));
1056 TSRMLS_SET_CTX(ares
->tsrm_ls
);
1057 zend_llist_init(&ares
->queries
, sizeof(php_ares_query
*), (llist_dtor_func_t
) php_ares_query_llist_dtor
, 0);
1058 php_ares_options_ctor(&ares
->options
, opt_array
? Z_ARRVAL_P(opt_array
) : NULL
);
1060 if (ARES_SUCCESS
!= (err
= ares_init_options(&ares
->channel
, &ares
->options
.strct
, ares
->options
.flags
))) {
1061 php_ares_options_dtor(&ares
->options
);
1062 zend_llist_destroy(&ares
->queries
);
1064 RETURN_ARES_ERROR(err
);
1067 ZEND_REGISTER_RESOURCE(return_value
, ares
, le_ares
);
1071 /* {{{ proto void ares_destroy(resource ares)
1072 Destroy the ares handle */
1073 static PHP_FUNCTION(ares_destroy
)
1078 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1079 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1080 if (ares
->in_callback
) {
1081 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Cannot destroy ares handle while in callback");
1083 zend_list_delete(Z_LVAL_P(rsrc
));
1089 /* {{{ proto string ares_strerror(int status)
1090 Get description of status code */
1091 static PHP_FUNCTION(ares_strerror
)
1094 #ifdef HAVE_OLD_ARES_STRERROR
1099 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &err
)) {
1103 #ifdef HAVE_OLD_ARES_STRERROR
1104 __err
= ares_strerror(err
, &__tmp
);
1105 RETVAL_STRING(estrdup(__err
), 0);
1107 ares_free_errmem(__tmp
);
1110 RETURN_STRING(estrdup(ares_strerror(err
)), 0);
1115 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
1116 Compose a custom query */
1117 static PHP_FUNCTION(ares_mkquery
)
1119 char *name_str
, *query_str
;
1120 int name_len
, query_len
, err
;
1121 long dnsclass
, type
, id
, rd
;
1123 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sllll", &name_str
, &name_len
, &dnsclass
, &type
, &id
, &rd
)) {
1127 if (ARES_SUCCESS
!= (err
= ares_mkquery(name_str
, dnsclass
, type
, id
, rd
, (unsigned char **) &query_str
, &query_len
))) {
1128 RETURN_ARES_ERROR(err
);
1130 RETVAL_STRINGL(query_str
, query_len
, 1);
1131 ares_free_string(query_str
);
1135 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1136 Issue a domain search for name */
1137 static PHP_FUNCTION(ares_search
)
1139 zval
*rsrc
, *cb
= NULL
;
1141 php_ares_query
*query
;
1144 long dnsclass
= C_IN
, type
= T_A
;
1146 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
1149 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1151 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1152 RETURN_ARES_CB_ERROR("second");
1155 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1156 php_ares_query_rsrc(query
, return_value
);
1157 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEARCH
, name
, name_len
, type
, dnsclass
);
1158 ares_search(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
1162 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
1163 Issue a single DNS query */
1164 static PHP_FUNCTION(ares_query
)
1166 zval
*rsrc
, *cb
= NULL
;
1168 php_ares_query
*query
;
1171 long dnsclass
= C_IN
, type
= T_A
;
1173 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
1176 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1178 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1179 RETURN_ARES_CB_ERROR("second");
1182 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1183 php_ares_query_rsrc(query
, return_value
);
1184 php_ares_query_pckt(query
, PHP_ARES_PCKT_QUERY
, name
, name_len
, type
, dnsclass
);
1185 ares_query(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
1189 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
1190 Send custom query */
1191 static PHP_FUNCTION(ares_send
)
1193 zval
*rsrc
, *cb
= NULL
;
1195 php_ares_query
*query
;
1199 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s", &rsrc
, &cb
, &buf
, &len
)) {
1202 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1204 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1205 RETURN_ARES_CB_ERROR("second");
1208 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
1209 php_ares_query_rsrc(query
, return_value
);
1210 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEND
, buf
, len
);
1211 ares_send(ares
->channel
, (const unsigned char *) buf
, len
, php_ares_callback_func
, query
);
1215 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
1217 static PHP_FUNCTION(ares_gethostbyname
)
1219 zval
*rsrc
, *cb
= NULL
;
1221 php_ares_query
*query
;
1224 long family
= AF_INET
;
1226 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &name
, &name_len
, &family
)) {
1229 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1231 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1232 RETURN_ARES_CB_ERROR("second");
1235 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
1236 php_ares_query_rsrc(query
, return_value
);
1237 php_ares_query_pckt(query
, PHP_ARES_PCKT_HNAME
, name
, name_len
, family
);
1238 ares_gethostbyname(ares
->channel
, name
, family
, php_ares_host_callback_func
, query
);
1242 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
1243 Get host by address */
1244 static PHP_FUNCTION(ares_gethostbyaddr
)
1246 zval
*rsrc
, *cb
= NULL
;
1248 php_ares_query
*query
;
1251 long family
= AF_INET
;
1255 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &addr
, &addr_len
, &family
)) {
1258 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1260 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1261 PHP_ARES_CB_ERROR("second");
1267 sa
= emalloc(sa_len
= sizeof(struct in_addr
));
1270 sa
= emalloc(sa_len
= sizeof(struct in6_addr
));
1273 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1278 if (1 > inet_pton(family
, addr
, sa
)) {
1279 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1282 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
1283 php_ares_query_rsrc(query
, return_value
);
1284 php_ares_query_pckt(query
, PHP_ARES_PCKT_HADDR
, addr
, addr_len
, family
);
1285 ares_gethostbyaddr(ares
->channel
, sa
, sa_len
, family
, php_ares_host_callback_func
, query
);
1291 #ifdef HAVE_ARES_GETNAMEINFO
1292 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1294 static PHP_FUNCTION(ares_getnameinfo
)
1296 zval
*rsrc
, *cb
= NULL
;
1298 php_ares_query
*query
;
1301 long flags
, port
= 0, family
= AF_INET
;
1302 struct sockaddr
*sa
;
1303 struct sockaddr_in
*in
;
1304 struct sockaddr_in6
*in6
;
1307 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!ls|ll", &rsrc
, &cb
, &flags
, &addr
, &addr_len
, &family
, &port
)) {
1310 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1312 if (cb
&& !PHP_ARES_IS_CALLABLE(cb
, 0, NULL
)) {
1313 PHP_ARES_CB_ERROR("second");
1320 in
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in
));
1321 in
->sin_family
= AF_INET
;
1322 in
->sin_port
= htons((unsigned short) port
);
1323 if (1 > inet_pton(in
->sin_family
, addr
, &in
->sin_addr
)) {
1324 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1327 sa
= (struct sockaddr
*) in
;
1330 in6
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in6
));
1331 in6
->sin6_family
= AF_INET6
;
1332 in6
->sin6_port
= htons((unsigned short) port
);
1333 if (1 > inet_pton(in6
->sin6_family
, addr
, &in6
->sin6_addr
)) {
1334 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1337 sa
= (struct sockaddr
*) in6
;
1340 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither AF_INET nor AF_INET6");
1345 if (Z_BVAL_P(return_value
)) {
1346 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_NINFO
, ares
, cb
);
1347 php_ares_query_rsrc(query
, return_value
);
1348 php_ares_query_pckt(query
, PHP_ARES_PCKT_NINFO
, flags
, addr
, addr_len
, family
, port
);
1349 ares_getnameinfo(ares
->channel
, sa
, sa_len
, flags
, php_ares_nameinfo_callback_func
, query
);
1356 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1357 Check a query for its result */
1358 static PHP_FUNCTION(ares_result
)
1360 zval
*rsrc
, *zerrno
= NULL
, *zerror
= NULL
;
1361 php_ares_query
*query
;
1363 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|zz", &rsrc
, &zerrno
, &zerror
)) {
1366 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1370 ZVAL_LONG(zerrno
, query
->error
);
1377 switch (query
->error
) {
1379 switch (query
->type
) {
1380 case PHP_ARES_CB_STD
:
1381 if (query
->result
.std
.arr
) {
1382 RETVAL_ZVAL(query
->result
.std
.arr
, 1, 0);
1384 RETVAL_STRINGL(query
->result
.std
.buf
, query
->result
.std
.len
, 1);
1387 case PHP_ARES_CB_HOST
:
1388 object_init(return_value
);
1389 php_ares_hostent_to_struct(&query
->result
.host
, HASH_OF(return_value
));
1391 case PHP_ARES_CB_NINFO
:
1392 object_init(return_value
);
1393 add_property_string(return_value
, "node", query
->result
.ninfo
.node
? query
->result
.ninfo
.node
: "", 1);
1394 add_property_string(return_value
, "service", query
->result
.ninfo
.service
? query
->result
.ninfo
.service
: "", 1);
1403 #ifdef HAVE_OLD_ARES_STRERROR
1405 const char *__err
= ares_strerror(query
->error
, &__tmp
);
1406 ZVAL_STRING(zerror
, estrdup(__err
), 0);
1407 if (__tmp
) ares_free_errmem(__tmp
);
1409 ZVAL_STRING(zerror
, estrdup(ares_strerror(query
->error
)), 0);
1418 /* {{{ proto object ares_packet(resource query)
1419 Check a query for its question packet */
1420 static PHP_FUNCTION(ares_packet
)
1423 php_ares_query
*query
;
1425 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1428 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1430 object_init(return_value
);
1431 add_property_long(return_value
, "type", query
->packet
.type
);
1432 add_property_null(return_value
, "search");
1433 add_property_null(return_value
, "query");
1434 add_property_null(return_value
, "send");
1435 add_property_null(return_value
, "gethostbyname");
1436 add_property_null(return_value
, "gethostbyaddr");
1437 add_property_null(return_value
, "getnameinfo");
1438 MAKE_STD_ZVAL(prop
);
1440 switch (query
->packet
.type
) {
1441 case PHP_ARES_PCKT_SEARCH
:
1443 add_property_stringl(prop
, "name", query
->packet
.data
.search
.name
, query
->packet
.data
.search
.name_len
, 1);
1444 add_property_long(prop
, "type", query
->packet
.data
.search
.type
);
1445 add_property_long(prop
, "dnsclass", query
->packet
.data
.search
.dnsclass
);
1446 add_property_zval(return_value
, "search", prop
);
1449 case PHP_ARES_PCKT_QUERY
:
1451 add_property_stringl(prop
, "name", query
->packet
.data
.query
.name
, query
->packet
.data
.query
.name_len
, 1);
1452 add_property_long(prop
, "type", query
->packet
.data
.query
.type
);
1453 add_property_long(prop
, "dnsclass", query
->packet
.data
.query
.dnsclass
);
1454 add_property_zval(return_value
, "query", prop
);
1457 case PHP_ARES_PCKT_SEND
:
1458 ZVAL_STRINGL(prop
, query
->packet
.data
.send
.buf
, query
->packet
.data
.send
.len
, 1);
1459 add_property_zval(return_value
, "send", prop
);
1462 case PHP_ARES_PCKT_HNAME
:
1464 add_property_stringl(prop
, "name", query
->packet
.data
.hname
.name
, query
->packet
.data
.hname
.name_len
, 1);
1465 add_property_long(prop
, "family", query
->packet
.data
.hname
.family
);
1466 add_property_zval(return_value
, "gethostbyname", prop
);
1469 case PHP_ARES_PCKT_HADDR
:
1471 add_property_stringl(prop
, "addr", query
->packet
.data
.haddr
.addr
, query
->packet
.data
.haddr
.addr_len
, 1);
1472 add_property_long(prop
, "family", query
->packet
.data
.haddr
.family
);
1473 add_property_zval(return_value
, "gethostbyaddr", prop
);
1476 case PHP_ARES_PCKT_NINFO
:
1478 add_property_long(prop
, "flags", query
->packet
.data
.ninfo
.flags
);
1479 add_property_stringl(prop
, "addr", query
->packet
.data
.ninfo
.addr
, query
->packet
.data
.ninfo
.addr_len
, 1);
1480 add_property_long(prop
, "family", query
->packet
.data
.ninfo
.family
);
1481 add_property_long(prop
, "port", query
->packet
.data
.ninfo
.port
);
1482 add_property_zval(return_value
, "getnameinfo", prop
);
1486 zval_ptr_dtor(&prop
);
1490 #ifdef HAVE_ARES_CANCEL
1491 /* {{{ proto void ares_cancel(resource ares)
1492 Cancel pending queries */
1493 static PHP_FUNCTION(ares_cancel
)
1498 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1499 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1500 ares_cancel(ares
->channel
);
1506 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1507 Process all pending queries */
1508 static PHP_FUNCTION(ares_process_all
)
1512 long max_timeout
= -1;
1514 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1517 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1519 while (php_ares_process(ares
, max_timeout
));
1523 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1524 Process once and return whether it should be called again */
1525 static PHP_FUNCTION(ares_process_once
)
1529 long max_timeout
= -1;
1531 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1534 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1536 RETVAL_BOOL(php_ares_process(ares
, max_timeout
));
1540 /* {{{ proto void ares_process(resource ares, array read, array write)
1542 static PHP_FUNCTION(ares_process
)
1544 zval
*rsrc
, *read
= NULL
, *write
= NULL
;
1548 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|a!a!", &rsrc
, &read
, &write
)) {
1551 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1556 php_ares_extract_fds(read
, write
, &R
, &W
);
1557 ares_process(ares
->channel
, &R
, &W
);
1561 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1563 static PHP_FUNCTION(ares_select
)
1565 zval
*read
= NULL
, *write
= NULL
;
1571 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "aal", &read
, &write
, &timeout
)) {
1576 tv
.tv_sec
= timeout
/ 1000;
1577 tv
.tv_usec
= timeout
% (timeout
* 1000);
1586 nfds
= php_ares_extract_fds(read
, write
, &R
, &W
);
1587 if (-1 < select(nfds
, &R
, &W
, NULL
, &tv
)) {
1588 zend_hash_clean(Z_ARRVAL_P(read
));
1589 zend_hash_clean(Z_ARRVAL_P(write
));
1590 php_ares_publish_fds(&R
, &W
, read
, write
);
1597 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1598 Get suggested select timeout in ms */
1599 static PHP_FUNCTION(ares_timeout
)
1602 long max_timeout
= -1;
1603 struct timeval tv
, *tvptr
;
1606 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1609 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1611 if ((tvptr
= php_ares_timeout(ares
, max_timeout
, &tv
))) {
1612 RETURN_LONG(tvptr
->tv_sec
* 1000 + tvptr
->tv_usec
/ 1000);
1618 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1619 Get file descriptors */
1620 static PHP_FUNCTION(ares_fds
)
1622 zval
*rsrc
, *read
, *write
;
1626 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rzz", &rsrc
, &read
, &write
)) {
1629 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1638 ares_fds(ares
->channel
, &R
, &W
);
1639 RETVAL_LONG(php_ares_publish_fds(&R
, &W
, read
, write
));
1643 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor
)
1645 php_ares
*ares
= (php_ares
*) rsrc
->ptr
;
1647 ares_destroy(ares
->channel
);
1648 zend_llist_destroy(&ares
->queries
);
1649 php_ares_options_dtor(&ares
->options
);
1653 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor
)
1655 php_ares_query
*query
= (php_ares_query
*) rsrc
->ptr
;
1657 php_ares_query_dtor(query
);
1661 /* {{{ PHP_MINIT_FUNCTION */
1662 static PHP_MINIT_FUNCTION(ares
)
1664 #ifdef HAVE_ARES_LIBRARY_INIT
1665 if (ARES_SUCCESS
!= ares_library_init(ARES_LIB_INIT_ALL
)) {
1669 #ifdef HAVE_ARES_VERSION
1671 int ares_version_num
;
1672 ares_version(&ares_version_num
);
1674 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num
, CONST_PERSISTENT
|CONST_CS
);
1678 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS
, CONST_PERSISTENT
|CONST_CS
);
1679 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA
, CONST_PERSISTENT
|CONST_CS
);
1680 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR
, CONST_PERSISTENT
|CONST_CS
);
1681 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL
, CONST_PERSISTENT
|CONST_CS
);
1682 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND
, CONST_PERSISTENT
|CONST_CS
);
1683 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP
, CONST_PERSISTENT
|CONST_CS
);
1684 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1685 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY
, CONST_PERSISTENT
|CONST_CS
);
1686 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME
, CONST_PERSISTENT
|CONST_CS
);
1687 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY
, CONST_PERSISTENT
|CONST_CS
);
1688 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP
, CONST_PERSISTENT
|CONST_CS
);
1689 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1690 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT
, CONST_PERSISTENT
|CONST_CS
);
1691 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF
, CONST_PERSISTENT
|CONST_CS
);
1692 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE
, CONST_PERSISTENT
|CONST_CS
);
1693 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM
, CONST_PERSISTENT
|CONST_CS
);
1694 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION
, CONST_PERSISTENT
|CONST_CS
);
1696 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR
, CONST_PERSISTENT
|CONST_CS
);
1698 #ifdef ARES_EBADFLAGS
1699 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS
, CONST_PERSISTENT
|CONST_CS
);
1702 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME
, CONST_PERSISTENT
|CONST_CS
);
1704 #ifdef ARES_EBADHINTS
1705 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS
, CONST_PERSISTENT
|CONST_CS
);
1707 #ifdef ARES_ENOTINITIALIZED
1708 REGISTER_LONG_CONSTANT("ARES_ENOTINITIALIZED", ARES_ENOTINITIALIZED
, CONST_PERSISTENT
|CONST_CS
);
1710 #ifdef ARES_ELOADIPHLPAPI
1711 REGISTER_LONG_CONSTANT("ARES_ELOADIPHLPAPI", ARES_ELOADIPHLPAPI
, CONST_PERSISTENT
|CONST_CS
);
1713 #ifdef ARES_EADDRGETNETWORKPARAMS
1714 REGISTER_LONG_CONSTANT("ARES_EADDRGETNETWORKPARAMS", ARES_EADDRGETNETWORKPARAMS
, CONST_PERSISTENT
|CONST_CS
);
1717 /* More error codes */
1718 #define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
1720 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC
, CONST_PERSISTENT
|CONST_CS
);
1721 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY
, CONST_PERSISTENT
|CONST_CS
);
1722 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC
, CONST_PERSISTENT
|CONST_CS
);
1723 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE
, CONST_PERSISTENT
|CONST_CS
);
1724 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN
, CONST_PERSISTENT
|CONST_CS
);
1725 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH
, CONST_PERSISTENT
|CONST_CS
);
1726 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES
, CONST_PERSISTENT
|CONST_CS
);
1727 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP
, CONST_PERSISTENT
|CONST_CS
);
1730 * Address Family Constants
1732 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET
, CONST_PERSISTENT
|CONST_CS
);
1733 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6
, CONST_PERSISTENT
|CONST_CS
);
1736 * Name Info constants
1738 #ifdef ARES_NI_NOFQDN
1739 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN
, CONST_PERSISTENT
|CONST_CS
);
1741 #ifdef ARES_NI_NUMERICHOST
1742 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
1744 #ifdef ARES_NI_NAMEREQD
1745 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD
, CONST_PERSISTENT
|CONST_CS
);
1747 #ifdef ARES_NI_NUMERICSERV
1748 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
1750 #ifdef ARES_NI_DGRAM
1751 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM
, CONST_PERSISTENT
|CONST_CS
);
1754 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP
, CONST_PERSISTENT
|CONST_CS
);
1757 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP
, CONST_PERSISTENT
|CONST_CS
);
1760 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP
, CONST_PERSISTENT
|CONST_CS
);
1763 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP
, CONST_PERSISTENT
|CONST_CS
);
1765 #ifdef ARES_NI_NUMERICSCOPE
1766 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE
, CONST_PERSISTENT
|CONST_CS
);
1768 #ifdef ARES_NI_LOOKUPHOST
1769 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST
, CONST_PERSISTENT
|CONST_CS
);
1771 #ifdef ARES_NI_LOOKUPSERVICE
1772 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE
, CONST_PERSISTENT
|CONST_CS
);
1775 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN
, CONST_PERSISTENT
|CONST_CS
);
1777 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1778 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
1780 #ifdef ARES_NI_IDN_USE_STD
1781 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
1785 * Address Info constants
1787 #ifdef ARES_AI_CANONNAME
1788 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME
, CONST_PERSISTENT
|CONST_CS
);
1790 #ifdef ARES_AI_NUMERICHOST
1791 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
1793 #ifdef ARES_AI_PASSIVE
1794 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE
, CONST_PERSISTENT
|CONST_CS
);
1796 #ifdef ARES_AI_NUMERICSERV
1797 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
1800 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V
, CONST_PERSISTENT
|CONST_CS
);
1803 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL
, CONST_PERSISTENT
|CONST_CS
);
1805 #ifdef ARES_AI_ADDRCONFIG
1806 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG
, CONST_PERSISTENT
|CONST_CS
);
1809 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN
, CONST_PERSISTENT
|CONST_CS
);
1811 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1812 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
1814 #ifdef ARES_AI_IDN_USE_STD
1815 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
1817 #ifdef ARES_AI_CANONIDN
1818 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN
, CONST_PERSISTENT
|CONST_CS
);
1821 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK
, CONST_PERSISTENT
|CONST_CS
);
1823 #ifdef ARES_GETSOCK_MAXNUM
1824 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM
, CONST_PERSISTENT
|CONST_CS
);
1828 * ns_t (type) constants (arpa/nameser.h)
1831 /* (1) Host address. */
1832 REGISTER_LONG_CONSTANT("ARES_T_A", T_A
, CONST_CS
|CONST_PERSISTENT
);
1835 /* (2) Authoritative server. */
1836 REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS
, CONST_CS
|CONST_PERSISTENT
);
1839 /* (3) Mail destination. */
1840 REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD
, CONST_CS
|CONST_PERSISTENT
);
1843 /* (4) Mail forwarder. */
1844 REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF
, CONST_CS
|CONST_PERSISTENT
);
1847 /* (5) Canonical name. */
1848 REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME
, CONST_CS
|CONST_PERSISTENT
);
1851 /* (6) Start of authority zone. */
1852 REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA
, CONST_CS
|CONST_PERSISTENT
);
1855 /* (7) Mailbox domain name. */
1856 REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB
, CONST_CS
|CONST_PERSISTENT
);
1859 /* (8) Mail group member. */
1860 REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG
, CONST_CS
|CONST_PERSISTENT
);
1863 /* (9) Mail rename name. */
1864 REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR
, CONST_CS
|CONST_PERSISTENT
);
1867 /* (10) Null resource record. */
1868 REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL
, CONST_CS
|CONST_PERSISTENT
);
1871 /* (11) Well known service. */
1872 REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS
, CONST_CS
|CONST_PERSISTENT
);
1875 /* (12) Domain name pointer. */
1876 REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR
, CONST_CS
|CONST_PERSISTENT
);
1879 /* (13) Host information. */
1880 REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO
, CONST_CS
|CONST_PERSISTENT
);
1883 /* (14) Mailbox information. */
1884 REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO
, CONST_CS
|CONST_PERSISTENT
);
1887 /* (15) Mail routing information. */
1888 REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX
, CONST_CS
|CONST_PERSISTENT
);
1891 /* (16) Text strings. */
1892 REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT
, CONST_CS
|CONST_PERSISTENT
);
1895 /* (17) Responsible person. */
1896 REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP
, CONST_CS
|CONST_PERSISTENT
);
1899 /* (18) AFS cell database. */
1900 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB
, CONST_CS
|CONST_PERSISTENT
);
1903 /* (19) X_25 calling address. */
1904 REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25
, CONST_CS
|CONST_PERSISTENT
);
1907 /* (20) ISDN calling address. */
1908 REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN
, CONST_CS
|CONST_PERSISTENT
);
1912 REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT
, CONST_CS
|CONST_PERSISTENT
);
1915 /* (22) NSAP address. */
1916 REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP
, CONST_CS
|CONST_PERSISTENT
);
1919 /* (23) Reverse NSAP lookup (deprecated). */
1920 REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR
, CONST_CS
|CONST_PERSISTENT
);
1923 /* (24) Security signature. */
1924 REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG
, CONST_CS
|CONST_PERSISTENT
);
1927 /* (25) Security key. */
1928 REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY
, CONST_CS
|CONST_PERSISTENT
);
1931 /* (26) X.400 mail mapping. */
1932 REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX
, CONST_CS
|CONST_PERSISTENT
);
1935 /* (27) Geographical position (withdrawn). */
1936 REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS
, CONST_CS
|CONST_PERSISTENT
);
1939 /* (28) Ip6 Address. */
1940 REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA
, CONST_CS
|CONST_PERSISTENT
);
1943 /* (29) Location Information. */
1944 REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC
, CONST_CS
|CONST_PERSISTENT
);
1947 /* (30) Next domain (security). */
1948 REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT
, CONST_CS
|CONST_PERSISTENT
);
1951 /* (31) Endpoint identifier. */
1952 REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID
, CONST_CS
|CONST_PERSISTENT
);
1955 /* (32) Nimrod Locator. */
1956 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC
, CONST_CS
|CONST_PERSISTENT
);
1959 /* (33) Server Selection. */
1960 REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV
, CONST_CS
|CONST_PERSISTENT
);
1963 /* (34) ATM Address */
1964 REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA
, CONST_CS
|CONST_PERSISTENT
);
1967 /* (35) Naming Authority Pointer */
1968 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR
, CONST_CS
|CONST_PERSISTENT
);
1971 /* (36) Key Exchange */
1972 REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX
, CONST_CS
|CONST_PERSISTENT
);
1975 /* (37) Certification record */
1976 REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT
, CONST_CS
|CONST_PERSISTENT
);
1979 /* (38) IPv6 address (deprecates AAAA) */
1980 REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6
, CONST_CS
|CONST_PERSISTENT
);
1983 /* (39) Non-terminal DNAME (for IPv6) */
1984 REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME
, CONST_CS
|CONST_PERSISTENT
);
1987 /* (40) Kitchen sink (experimentatl) */
1988 REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK
, CONST_CS
|CONST_PERSISTENT
);
1991 /* (41) EDNS0 option (meta-RR) */
1992 REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT
, CONST_CS
|CONST_PERSISTENT
);
1994 /* (250) Transaction signature. */
1995 REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG
, CONST_CS
|CONST_PERSISTENT
);
1997 /* (251) Incremental zone transfer. */
1998 REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR
, CONST_CS
|CONST_PERSISTENT
);
2001 /* (252) Transfer zone of authority. */
2002 REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR
, CONST_CS
|CONST_PERSISTENT
);
2005 /* (253) Transfer mailbox records. */
2006 REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB
, CONST_CS
|CONST_PERSISTENT
);
2009 /* (254) Transfer mail agent records. */
2010 REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA
, CONST_CS
|CONST_PERSISTENT
);
2013 /* (255) Wildcard match. */
2014 REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY
, CONST_CS
|CONST_PERSISTENT
);
2018 * ns_c (dnsclass) constants (arpa/nameser.h)
2023 REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN
, CONST_CS
|CONST_PERSISTENT
);
2026 /* (2) unallocated/unsupported. */
2027 REGISTER_LONG_CONSTANT("ARES_C_2", C_2
, CONST_CS
|CONST_PERSISTENT
);
2030 /* (3) MIT Chaos-net. */
2031 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS
, CONST_CS
|CONST_PERSISTENT
);
2034 /* (4) MIT Hesiod. */
2035 REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS
, CONST_CS
|CONST_PERSISTENT
);
2038 /* (254) for prereq. sections in update requests */
2039 REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE
, CONST_CS
|CONST_PERSISTENT
);
2042 /* (255) Wildcard match. */
2043 REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY
, CONST_CS
|CONST_PERSISTENT
);
2046 le_ares
= zend_register_list_destructors_ex(php_ares_le_dtor
, NULL
, PHP_ARES_LE_NAME
, module_number
);
2047 le_ares_query
= zend_register_list_destructors_ex(php_ares_query_le_dtor
, NULL
, PHP_ARES_QUERY_LE_NAME
, module_number
);
2053 /* {{{ PHP_MSHUTDOWN_FUNCTION */
2054 static PHP_MSHUTDOWN_FUNCTION(ares
)
2056 #ifdef HAVE_ARES_LIBRARY_CLEANUP
2057 ares_library_cleanup();
2063 /* {{{ PHP_MINFO_FUNCTION */
2064 static PHP_MINFO_FUNCTION(ares
)
2066 php_info_print_table_start();
2067 php_info_print_table_header(2, "AsyncResolver support", "enabled");
2068 php_info_print_table_row(2, "Version", PHP_ARES_VERSION
);
2069 php_info_print_table_end();
2071 php_info_print_table_start();
2072 php_info_print_table_header(3, "Used Library", "compiled", "linked");
2073 php_info_print_table_row(3,
2075 #ifdef ARES_VERSION_STR
2080 #ifdef HAVE_ARES_VERSION
2086 php_info_print_table_end();
2090 #ifdef ZEND_ENGINE_2
2091 ZEND_BEGIN_ARG_INFO(ai_ares_select
, 0)
2092 ZEND_ARG_PASS_INFO(1)
2093 ZEND_ARG_PASS_INFO(1)
2094 ZEND_ARG_PASS_INFO(0)
2095 ZEND_END_ARG_INFO();
2097 ZEND_BEGIN_ARG_INFO(ai_ares_result
, 0)
2098 ZEND_ARG_PASS_INFO(0)
2099 ZEND_ARG_PASS_INFO(1)
2100 ZEND_ARG_PASS_INFO(1)
2101 ZEND_END_ARG_INFO();
2103 ZEND_BEGIN_ARG_INFO(ai_ares_fds
, 0)
2104 ZEND_ARG_PASS_INFO(0)
2105 ZEND_ARG_PASS_INFO(1)
2106 ZEND_ARG_PASS_INFO(1)
2107 ZEND_END_ARG_INFO();
2109 static unsigned char ai_ares_select
[] = {3, BYREF_FORCE
, BYREF_FORCE
, BYREF_NONE
};
2110 static unsigned char ai_ares_result
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
2111 static unsigned char ai_ares_fds
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
2114 /* {{{ ares_functions[] */
2115 zend_function_entry ares_functions
[] = {
2116 #ifdef HAVE_ARES_VERSION
2117 PHP_FE(ares_version
, NULL
)
2119 PHP_FE(ares_init
, NULL
)
2120 PHP_FE(ares_destroy
, NULL
)
2121 PHP_FE(ares_strerror
, NULL
)
2122 #ifdef HAVE_ARES_CANCEL
2123 PHP_FE(ares_cancel
, NULL
)
2125 PHP_FE(ares_search
, NULL
)
2126 PHP_FE(ares_query
, NULL
)
2127 PHP_FE(ares_send
, NULL
)
2128 PHP_FE(ares_mkquery
, NULL
)
2129 PHP_FE(ares_gethostbyname
, NULL
)
2130 PHP_FE(ares_gethostbyaddr
, NULL
)
2131 #ifdef HAVE_ARES_GETNAMEINFO
2132 PHP_FE(ares_getnameinfo
, NULL
)
2134 PHP_FE(ares_result
, ai_ares_result
)
2135 PHP_FE(ares_packet
, NULL
)
2136 PHP_FE(ares_process_all
, NULL
)
2137 PHP_FE(ares_process_once
, NULL
)
2138 PHP_FE(ares_process
, NULL
)
2139 PHP_FE(ares_select
, ai_ares_select
)
2140 PHP_FE(ares_fds
, ai_ares_fds
)
2141 PHP_FE(ares_timeout
, NULL
)
2146 /* {{{ ares_module_entry */
2147 zend_module_entry ares_module_entry
= {
2148 STANDARD_MODULE_HEADER
,
2152 PHP_MSHUTDOWN(ares
),
2157 STANDARD_MODULE_PROPERTIES
2161 #ifdef COMPILE_DL_ARES
2162 ZEND_GET_MODULE(ares
)
2170 * vim600: noet sw=4 ts=4 fdm=marker
2171 * vim<600: noet sw=4 ts=4