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>
44 # define IS_CALLABLE(a,b,c) 1
46 # undef TSRMLS_SET_CTX
47 # define TSRMLS_SET_CTX
48 # undef TSRMLS_FETCH_FROM_CTX
49 # define TSRMLS_FETCH_FROM_CTX
52 #if (PHP_MAJOR_VERSION > 5) || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3))
53 # define ADDREF(z) Z_ADDREF_P(z)
54 # define IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c) TSRMLS_CC)
56 # define ADDREF(z) ZVAL_ADDREF(z)
57 # define IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
60 #define PHP_ARES_LE_NAME "AsyncResolver"
61 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
63 static int le_ares_query
;
65 #ifdef HAVE_OLD_ARES_STRERROR
66 # define PHP_ARES_ERROR(err) { \
68 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err, &__tmp)); \
69 if (__tmp) ares_free_errmem(__tmp); \
72 # define PHP_ARES_ERROR(err) \
73 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
76 #define RETURN_ARES_ERROR(err) \
77 PHP_ARES_ERROR(err); \
79 #define PHP_ARES_CB_ERROR(param) \
80 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected the " param " argument to be a valid callback")
81 #define RETURN_ARES_CB_ERROR(param) \
82 PHP_ARES_CB_ERROR(param); \
86 typedef struct _php_ares_options
{
87 struct ares_options strct
;
91 typedef struct _php_ares
{
93 php_ares_options options
;
96 unsigned in_callback
:1;
100 typedef enum _php_ares_query_type
{
104 } php_ares_query_type
;
106 typedef enum _php_ares_query_packet_type
{
107 PHP_ARES_PCKT_SEARCH
,
113 } php_ares_query_packet_type
;
115 typedef union _php_ares_query_packet_data
{
149 } php_ares_query_packet_data
;
151 typedef struct _php_ares_query_packet
{
152 php_ares_query_packet_type type
;
153 php_ares_query_packet_data data
;
154 } php_ares_query_packet
;
156 typedef union _php_ares_query_result
{
166 } php_ares_query_result
;
168 typedef struct _php_ares_query
{
173 php_ares_query_type type
;
174 php_ares_query_packet packet
;
175 php_ares_query_result result
;
179 local
struct hostent
*php_ares_hostent_ctor(struct hostent
*host
) /* {{{ */
182 host
= emalloc(sizeof(struct hostent
));
184 memset(host
, 0, sizeof(struct hostent
));
190 local
void php_ares_hostent_copy(struct hostent
*from
, struct hostent
*to
) /* {{{ */
195 memcpy(to
, from
, sizeof(struct hostent
));
196 to
->h_name
= estrdup(from
->h_name
);
197 for (c
= 0, ptr
= from
->h_aliases
; *ptr
; ++ptr
, ++c
);
198 to
->h_aliases
= ecalloc((c
+1), sizeof(char *));
199 for (i
= 0; i
< c
; ++i
) {
200 to
->h_aliases
[i
] = estrdup(from
->h_aliases
[i
]);
202 for (c
= 0, ptr
= from
->h_addr_list
; *ptr
; ++ptr
, ++c
);
203 to
->h_addr_list
= ecalloc((c
+1), sizeof(char *));
204 for (i
= 0; i
< c
; ++i
) {
205 to
->h_addr_list
[i
] = emalloc(from
->h_length
);
206 memcpy(to
->h_addr_list
[i
], from
->h_addr_list
[i
], from
->h_length
);
211 local
void php_ares_hostent_to_struct(struct hostent
*hostent
, HashTable
*ht
) /* {{{ */
217 Z_TYPE(array
) = IS_ARRAY
;
218 Z_ARRVAL(array
) = ht
;
221 add_assoc_string(&array
, "name", hostent
->h_name
, 1);
225 if (hostent
->h_aliases
) {
226 for (ptr
= hostent
->h_aliases
; *ptr
; ++ptr
) {
227 add_next_index_string(tmp
, *ptr
, 1);
230 add_assoc_zval(&array
, "aliases", tmp
);
231 add_assoc_long(&array
, "addrtype", hostent
->h_addrtype
);
235 if (hostent
->h_addr_list
) {
236 for (ptr
= hostent
->h_addr_list
; *ptr
; ++ptr
) {
239 if (inet_ntop(hostent
->h_addrtype
, *ptr
, name
, sizeof(name
)-1)) {
240 add_next_index_string(tmp
, name
, 1);
244 add_assoc_zval(&array
, "addrlist", tmp
);
249 local
void php_ares_hostent_dtor(struct hostent
*host
) /* {{{ */
253 STR_FREE(host
->h_name
);
254 if (host
->h_aliases
) {
255 for (ptr
= host
->h_aliases
; *ptr
; ++ptr
) {
258 efree(host
->h_aliases
);
260 if (host
->h_addr_list
) {
261 for (ptr
= host
->h_addr_list
; *ptr
; ++ptr
) {
264 efree(host
->h_addr_list
);
266 memset(host
, 0, sizeof(struct hostent
));
270 local
void php_ares_hostent_free(struct hostent
**host
) /* {{{ */
272 php_ares_hostent_dtor(*host
);
278 local php_ares_query
*php_ares_query_ctor(php_ares_query
*query
, php_ares_query_type type
, php_ares
*ares
, zval
*callback
) /* {{{ */
281 query
= emalloc(sizeof(php_ares_query
));
283 memset(query
, 0, sizeof(php_ares_query
));
291 query
->callback
= callback
;
298 local
void php_ares_query_rsrc(php_ares_query
*query
, zval
*return_value
) /* {{{ */
300 TSRMLS_FETCH_FROM_CTX(query
->ares
->tsrm_ls
);
302 ZEND_REGISTER_RESOURCE(return_value
, query
, le_ares_query
);
303 query
->id
= Z_LVAL_P(return_value
);
304 zend_list_addref(query
->id
);
305 zend_llist_add_element(&query
->ares
->queries
, &query
);
309 local
void php_ares_query_pckt(php_ares_query
*query
, php_ares_query_packet_type type
, ...)
315 va_start(argv
, type
);
317 switch (query
->packet
.type
= type
) {
318 case PHP_ARES_PCKT_SEARCH
:
319 buf
= va_arg(argv
, char *);
320 len
= va_arg(argv
, int);
321 query
->packet
.data
.search
.name
= estrndup(buf
, len
);
322 query
->packet
.data
.search
.name_len
= len
;
323 query
->packet
.data
.search
.type
= va_arg(argv
, long);
324 query
->packet
.data
.search
.dnsclass
= va_arg(argv
, long);
327 case PHP_ARES_PCKT_QUERY
:
328 buf
= va_arg(argv
, char *);
329 len
= va_arg(argv
, int);
330 query
->packet
.data
.query
.name
= estrndup(buf
, len
);
331 query
->packet
.data
.query
.name_len
= len
;
332 query
->packet
.data
.query
.type
= va_arg(argv
, long);
333 query
->packet
.data
.query
.dnsclass
= va_arg(argv
, long);
336 case PHP_ARES_PCKT_SEND
:
337 buf
= va_arg(argv
, char *);
338 len
= va_arg(argv
, int);
339 query
->packet
.data
.send
.buf
= estrndup(buf
, len
);
340 query
->packet
.data
.send
.len
= len
;
343 case PHP_ARES_PCKT_HNAME
:
344 buf
= va_arg(argv
, char *);
345 len
= va_arg(argv
, int);
346 query
->packet
.data
.hname
.name
= estrndup(buf
, len
);
347 query
->packet
.data
.hname
.name_len
= len
;
348 query
->packet
.data
.hname
.family
= va_arg(argv
, long);
351 case PHP_ARES_PCKT_HADDR
:
352 buf
= va_arg(argv
, char *);
353 len
= va_arg(argv
, int);
354 query
->packet
.data
.haddr
.addr
= estrndup(buf
, len
);
355 query
->packet
.data
.haddr
.addr_len
= len
;
356 query
->packet
.data
.haddr
.family
= va_arg(argv
, long);
359 case PHP_ARES_PCKT_NINFO
:
360 query
->packet
.data
.ninfo
.flags
= va_arg(argv
, long);
361 buf
= va_arg(argv
, char *);
362 len
= va_arg(argv
, int);
363 query
->packet
.data
.ninfo
.addr
= estrndup(buf
, len
);
364 query
->packet
.data
.ninfo
.addr_len
= len
;
365 query
->packet
.data
.ninfo
.family
= va_arg(argv
, long);
366 query
->packet
.data
.ninfo
.port
= va_arg(argv
, long);
373 local
void php_ares_query_dtor(php_ares_query
*query
) /* {{{ */
375 struct php_ares_query_packet_buf
{char *buf
;} *packet
;
377 packet
= (struct php_ares_query_packet_buf
*) &query
->packet
.data
;
381 switch (query
->type
) {
382 case PHP_ARES_CB_STD
:
383 STR_FREE(query
->result
.std
.buf
);
385 case PHP_ARES_CB_HOST
:
386 php_ares_hostent_dtor(&query
->result
.host
);
388 case PHP_ARES_CB_NINFO
:
389 STR_FREE(query
->result
.ninfo
.service
);
390 STR_FREE(query
->result
.ninfo
.node
);
393 if (query
->callback
) {
394 zval_ptr_dtor(&query
->callback
);
396 memset(query
, 0, sizeof(php_ares_query
));
400 local
void php_ares_query_free(php_ares_query
**query
) /* {{{ */
402 php_ares_query_dtor(*query
);
408 local php_ares_options
*php_ares_options_ctor(php_ares_options
*options
, HashTable
*ht
) /* {{{ */
414 options
= emalloc(sizeof(php_ares_options
));
416 memset(options
, 0, sizeof(php_ares_options
));
418 if (ht
&& zend_hash_num_elements(ht
)) {
419 if ((SUCCESS
== zend_hash_find(ht
, "flags", sizeof("flags"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
420 options
->flags
|= ARES_OPT_FLAGS
;
421 options
->strct
.flags
= Z_LVAL_PP(opt
);
423 if ((SUCCESS
== zend_hash_find(ht
, "timeout", sizeof("timeout"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
424 options
->flags
|= ARES_OPT_TIMEOUT
;
425 options
->strct
.timeout
= Z_LVAL_PP(opt
);
427 if ((SUCCESS
== zend_hash_find(ht
, "tries", sizeof("tries"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
428 options
->flags
|= ARES_OPT_TRIES
;
429 options
->strct
.tries
= Z_LVAL_PP(opt
);
431 if ((SUCCESS
== zend_hash_find(ht
, "ndots", sizeof("ndots"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
432 options
->flags
|= ARES_OPT_NDOTS
;
433 options
->strct
.ndots
= Z_LVAL_PP(opt
);
435 if ((SUCCESS
== zend_hash_find(ht
, "udp_port", sizeof("udp_port"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
436 options
->flags
|= ARES_OPT_UDP_PORT
;
437 options
->strct
.udp_port
= htons((unsigned short) Z_LVAL_PP(opt
));
439 if ((SUCCESS
== zend_hash_find(ht
, "tcp_port", sizeof("tcp_port"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_LONG
)) {
440 options
->flags
|= ARES_OPT_TCP_PORT
;
441 options
->strct
.tcp_port
= htons((unsigned short) Z_LVAL_PP(opt
));
443 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
)))) {
444 options
->strct
.servers
= ecalloc(i
, sizeof(struct in_addr
));
445 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt
));
446 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_PP(opt
), (void *) &entry
);
447 zend_hash_move_forward(Z_ARRVAL_PP(opt
))) {
448 if (Z_TYPE_PP(entry
) == IS_STRING
) {
449 inet_aton(Z_STRVAL_PP(entry
), &options
->strct
.servers
[options
->strct
.nservers
++]);
452 if (options
->strct
.nservers
) {
453 options
->flags
|= ARES_OPT_SERVERS
;
456 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
)))) {
457 options
->strct
.domains
= ecalloc(i
, sizeof(char *));
458 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt
));
459 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_PP(opt
), (void *) &entry
);
460 zend_hash_move_forward(Z_ARRVAL_PP(opt
))) {
461 if (Z_TYPE_PP(entry
) == IS_STRING
) {
462 options
->strct
.domains
[options
->strct
.ndomains
++] = estrdup(Z_STRVAL_PP(entry
));
465 if (options
->strct
.ndomains
) {
466 options
->flags
|= ARES_OPT_DOMAINS
;
469 if ((SUCCESS
== zend_hash_find(ht
, "lookups", sizeof("lookups"), (void *) &opt
)) && (Z_TYPE_PP(opt
) == IS_STRING
)) {
470 options
->flags
|= ARES_OPT_LOOKUPS
;
471 options
->strct
.lookups
= estrdup(Z_STRVAL_PP(opt
));
479 local
void php_ares_options_dtor(php_ares_options
*options
) /* {{{ */
483 if (options
->strct
.servers
) {
484 efree(options
->strct
.servers
);
487 if (options
->strct
.domains
) {
488 for (i
= 0; i
< options
->strct
.ndomains
; ++i
) {
489 efree(options
->strct
.domains
[i
]);
491 efree(options
->strct
.domains
);
494 STR_FREE(options
->strct
.lookups
);
496 memset(options
, 0, sizeof(php_ares_options
));
500 local
void php_ares_options_free(php_ares_options
**options
) /* {{{ */
502 php_ares_options_dtor(*options
);
509 static void php_ares_callback_func_old(void *aq
, int status
, unsigned char *abuf
, int alen
)
511 php_ares_query
*q
= (php_ares_query
*) aq
;
512 zval
*params
[3], *retval
;
513 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
517 q
->result
.std
.buf
= estrndup((char *) abuf
, alen
);
518 q
->result
.std
.len
= alen
;
522 MAKE_STD_ZVAL(retval
);
523 MAKE_STD_ZVAL(params
[0]);
524 MAKE_STD_ZVAL(params
[1]);
525 MAKE_STD_ZVAL(params
[2]);
527 zend_list_addref(q
->id
);
528 Z_LVAL_P(params
[0]) = q
->id
;
529 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
530 ZVAL_LONG(params
[1], status
);
531 ZVAL_STRINGL(params
[2], (char *) abuf
, alen
, 1);
533 q
->ares
->in_callback
= 1;
534 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 3, params TSRMLS_CC
);
535 q
->ares
->in_callback
= 0;
537 zval_ptr_dtor(&retval
);
538 zval_ptr_dtor(¶ms
[0]);
539 zval_ptr_dtor(¶ms
[1]);
540 zval_ptr_dtor(¶ms
[2]);
544 static void php_ares_host_callback_func_old(void *aq
, int status
, struct hostent
*hostent
)
546 php_ares_query
*q
= (php_ares_query
*) aq
;
547 zval
*params
[3], *retval
;
548 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
552 php_ares_hostent_copy(hostent
, &q
->result
.host
);
556 MAKE_STD_ZVAL(retval
);
557 MAKE_STD_ZVAL(params
[0]);
558 MAKE_STD_ZVAL(params
[1]);
559 MAKE_STD_ZVAL(params
[2]);
561 zend_list_addref(q
->id
);
562 Z_LVAL_P(params
[0]) = q
->id
;
563 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
564 ZVAL_LONG(params
[1], status
);
565 object_init(params
[2]);
566 php_ares_hostent_to_struct(hostent
, HASH_OF(params
[2]));
568 q
->ares
->in_callback
= 1;
569 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 3, params TSRMLS_CC
);
570 q
->ares
->in_callback
= 0;
572 zval_ptr_dtor(&retval
);
573 zval_ptr_dtor(¶ms
[0]);
574 zval_ptr_dtor(¶ms
[1]);
575 zval_ptr_dtor(¶ms
[2]);
579 #ifdef HAVE_ARES_GETNAMEINFO
580 static void php_ares_nameinfo_callback_func_old(void *aq
, int status
, char *node
, char *service
)
582 php_ares_query
*q
= (php_ares_query
*) aq
;
583 zval
*params
[4], *retval
;
584 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
588 q
->result
.ninfo
.node
= estrdup(node
);
591 q
->result
.ninfo
.service
= estrdup(service
);
595 MAKE_STD_ZVAL(retval
);
596 MAKE_STD_ZVAL(params
[0]);
597 MAKE_STD_ZVAL(params
[1]);
598 MAKE_STD_ZVAL(params
[2]);
599 MAKE_STD_ZVAL(params
[3]);
601 zend_list_addref(q
->id
);
602 Z_LVAL_P(params
[0]) = q
->id
;
603 Z_TYPE_P(params
[0]) = IS_RESOURCE
;
604 ZVAL_LONG(params
[1], status
);
606 ZVAL_STRING(params
[2], node
, 1);
608 ZVAL_NULL(params
[2]);
611 ZVAL_STRING(params
[3], service
, 1);
613 ZVAL_NULL(params
[3]);
616 q
->ares
->in_callback
= 1;
617 call_user_function(EG(function_table
), NULL
, q
->callback
, retval
, 4, params TSRMLS_CC
);
618 q
->ares
->in_callback
= 0;
620 zval_ptr_dtor(&retval
);
621 zval_ptr_dtor(¶ms
[0]);
622 zval_ptr_dtor(¶ms
[1]);
623 zval_ptr_dtor(¶ms
[2]);
624 zval_ptr_dtor(¶ms
[3]);
629 #if PHP_ARES_NEW_CALLBACK_API
630 # define php_ares_callback_func php_ares_callback_func_new
631 static void php_ares_callback_func_new(void *aq
, int status
, int timeouts
, unsigned char *abuf
, int alen
)
633 php_ares_callback_func_old(aq
, status
, abuf
, alen
);
636 # define php_ares_host_callback_func php_ares_host_callback_func_new
637 static void php_ares_host_callback_func_new(void *aq
, int status
, int timeouts
, struct hostent
*hostent
)
639 php_ares_host_callback_func_old(aq
, status
, hostent
);
642 # ifdef HAVE_ARES_GETNAMEINFO
643 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
644 static void php_ares_nameinfo_callback_func_new(void *aq
, int status
, int timeouts
, char *node
, char *service
)
646 php_ares_nameinfo_callback_func_old(aq
, status
, node
, service
);
651 # define php_ares_callback_func php_ares_callback_func_old
652 # define php_ares_host_callback_func php_ares_host_callback_func_old
653 # ifdef HAVE_ARES_GETNAMEINFO
654 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
659 local
struct timeval
*php_ares_timeout(php_ares
*ares
, long max_timeout
, struct timeval
*tv_buf
) /* {{{ */
661 struct timeval maxtv
;
663 if (max_timeout
> -1) {
664 maxtv
.tv_sec
= max_timeout
/ 1000;
665 maxtv
.tv_usec
= max_timeout
% (max_timeout
* 1000);
668 return ares_timeout(ares
->channel
, max_timeout
> -1 ? &maxtv
: NULL
, tv_buf
);
672 local
int php_ares_process(php_ares
*ares
, long max_timeout
) /* {{{ */
681 if ((nfds
= ares_fds(ares
->channel
, &R
, &W
))) {
682 if (0 < select(nfds
, &R
, &W
, NULL
, php_ares_timeout(ares
, max_timeout
, &tv
))) {
683 ares_process(ares
->channel
, &R
, &W
);
691 local
int php_ares_publish_fds(fd_set
*R
, fd_set
*W
, zval
*r
, zval
*w
) /* {{{ */
695 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
696 if (FD_ISSET(i
, R
)) {
697 add_next_index_long(r
, i
);
704 for (i
= 0; i
< FD_SETSIZE
; ++i
) {
705 if (FD_ISSET(i
, W
)) {
706 add_next_index_long(w
, i
);
713 return nfds
? nfds
+ 1 : 0;
717 local
int php_ares_extract_fds(zval
*r
, zval
*w
, fd_set
*R
, fd_set
*W
) /* {{{ */
722 if (r
&& zend_hash_num_elements(Z_ARRVAL_P(r
))) {
723 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r
));
724 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(r
), (void *) &fd
);
725 zend_hash_move_forward(Z_ARRVAL_P(r
))) {
726 if (Z_TYPE_PP(fd
) == IS_LONG
) {
727 FD_SET(Z_LVAL_PP(fd
), R
);
728 if (Z_LVAL_PP(fd
) > nfds
) {
729 nfds
= Z_LVAL_PP(fd
);
735 if (w
&& zend_hash_num_elements(Z_ARRVAL_P(w
))) {
736 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w
));
737 SUCCESS
== zend_hash_get_current_data(Z_ARRVAL_P(w
), (void *) &fd
);
738 zend_hash_move_forward(Z_ARRVAL_P(w
))) {
739 if (Z_TYPE_PP(fd
) == IS_LONG
) {
740 FD_SET(Z_LVAL_PP(fd
), W
);
741 if (Z_LVAL_PP(fd
) > nfds
) {
742 nfds
= Z_LVAL_PP(fd
);
748 return nfds
? nfds
+ 1 : 0;
752 static void php_ares_query_llist_dtor(void *entry
)
754 php_ares_query
*q
= *(php_ares_query
**) entry
;
755 TSRMLS_FETCH_FROM_CTX(q
->ares
->tsrm_ls
);
756 zend_list_delete(q
->id
);
759 #ifdef HAVE_ARES_VERSION
760 /* {{{ proto string ares_version()
761 Get libares version */
762 static PHP_FUNCTION(ares_version
)
764 if (ZEND_NUM_ARGS()) {
768 RETURN_STRING(estrdup(ares_version(NULL
)), 0);
773 /* {{{ proto resource ares_init([array options])
774 Create an ares resource */
775 static PHP_FUNCTION(ares_init
)
777 zval
*opt_array
= NULL
;
778 php_ares
*ares
= NULL
;
781 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a!", &opt_array
)) {
785 ares
= emalloc(sizeof(php_ares
));
786 TSRMLS_SET_CTX(ares
->tsrm_ls
);
787 zend_llist_init(&ares
->queries
, sizeof(php_ares_query
*), (llist_dtor_func_t
) php_ares_query_llist_dtor
, 0);
788 php_ares_options_ctor(&ares
->options
, opt_array
? Z_ARRVAL_P(opt_array
) : NULL
);
790 if (ARES_SUCCESS
!= (err
= ares_init_options(&ares
->channel
, &ares
->options
.strct
, ares
->options
.flags
))) {
791 php_ares_options_dtor(&ares
->options
);
792 zend_llist_destroy(&ares
->queries
);
794 RETURN_ARES_ERROR(err
);
797 ZEND_REGISTER_RESOURCE(return_value
, ares
, le_ares
);
801 /* {{{ proto void ares_destroy(resource ares)
802 Destroy the ares handle */
803 static PHP_FUNCTION(ares_destroy
)
808 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
809 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
810 if (ares
->in_callback
) {
811 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Cannot destroy ares handle while in callback");
813 zend_list_delete(Z_LVAL_P(rsrc
));
819 /* {{{ proto string ares_strerror(int status)
820 Get description of status code */
821 static PHP_FUNCTION(ares_strerror
)
824 #ifdef HAVE_OLD_ARES_STRERROR
829 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &err
)) {
833 #ifdef HAVE_OLD_ARES_STRERROR
834 __err
= ares_strerror(err
, &__tmp
);
835 RETVAL_STRING(estrdup(__err
), 0);
837 ares_free_errmem(__tmp
);
840 RETURN_STRING(estrdup(ares_strerror(err
)), 0);
845 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
846 Compose a custom query */
847 static PHP_FUNCTION(ares_mkquery
)
849 char *name_str
, *query_str
;
850 int name_len
, query_len
, err
;
851 long dnsclass
, type
, id
, rd
;
853 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sllll", &name_str
, &name_len
, &dnsclass
, &type
, &id
, &rd
)) {
857 if (ARES_SUCCESS
!= (err
= ares_mkquery(name_str
, dnsclass
, type
, id
, rd
, (unsigned char **) &query_str
, &query_len
))) {
858 RETURN_ARES_ERROR(err
);
860 RETVAL_STRINGL(query_str
, query_len
, 1);
861 ares_free_string(query_str
);
865 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
866 Issue a domain search for name */
867 static PHP_FUNCTION(ares_search
)
869 zval
*rsrc
, *cb
= NULL
;
871 php_ares_query
*query
;
874 long dnsclass
= ns_c_in
, type
= ns_t_a
;
876 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
879 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
881 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
882 RETURN_ARES_CB_ERROR("second");
885 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
886 php_ares_query_rsrc(query
, return_value
);
887 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEARCH
, name
, name_len
, type
, dnsclass
);
888 ares_search(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
892 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
893 Issue a single DNS query */
894 static PHP_FUNCTION(ares_query
)
896 zval
*rsrc
, *cb
= NULL
;
898 php_ares_query
*query
;
901 long dnsclass
= ns_c_in
, type
= ns_t_a
;
903 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|ll", &rsrc
, &cb
, &name
, &name_len
, &type
, &dnsclass
)) {
906 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
908 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
909 RETURN_ARES_CB_ERROR("second");
912 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
913 php_ares_query_rsrc(query
, return_value
);
914 php_ares_query_pckt(query
, PHP_ARES_PCKT_QUERY
, name
, name_len
, type
, dnsclass
);
915 ares_query(ares
->channel
, name
, dnsclass
, type
, php_ares_callback_func
, query
);
919 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
921 static PHP_FUNCTION(ares_send
)
923 zval
*rsrc
, *cb
= NULL
;
925 php_ares_query
*query
;
929 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s", &rsrc
, &cb
, &buf
, &len
)) {
932 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
934 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
935 RETURN_ARES_CB_ERROR("second");
938 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_STD
, ares
, cb
);
939 php_ares_query_rsrc(query
, return_value
);
940 php_ares_query_pckt(query
, PHP_ARES_PCKT_SEND
, buf
, len
);
941 ares_send(ares
->channel
, (const unsigned char *) buf
, len
, php_ares_callback_func
, query
);
945 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
947 static PHP_FUNCTION(ares_gethostbyname
)
949 zval
*rsrc
, *cb
= NULL
;
951 php_ares_query
*query
;
954 long family
= AF_INET
;
956 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &name
, &name_len
, &family
)) {
959 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
961 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
962 RETURN_ARES_CB_ERROR("second");
965 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
966 php_ares_query_rsrc(query
, return_value
);
967 php_ares_query_pckt(query
, PHP_ARES_PCKT_HNAME
, name
, name_len
, family
);
968 ares_gethostbyname(ares
->channel
, name
, family
, php_ares_host_callback_func
, query
);
972 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
973 Get host by address */
974 static PHP_FUNCTION(ares_gethostbyaddr
)
976 zval
*rsrc
, *cb
= NULL
;
978 php_ares_query
*query
;
981 long family
= AF_INET
;
985 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!s|l", &rsrc
, &cb
, &addr
, &addr_len
, &family
)) {
988 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
990 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
991 PHP_ARES_CB_ERROR("second");
997 sa
= emalloc(sa_len
= sizeof(struct in_addr
));
1000 sa
= emalloc(sa_len
= sizeof(struct in6_addr
));
1003 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1008 if (1 > inet_pton(family
, addr
, sa
)) {
1009 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1012 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_HOST
, ares
, cb
);
1013 php_ares_query_rsrc(query
, return_value
);
1014 php_ares_query_pckt(query
, PHP_ARES_PCKT_HADDR
, addr
, addr_len
, family
);
1015 ares_gethostbyaddr(ares
->channel
, sa
, sa_len
, family
, php_ares_host_callback_func
, query
);
1021 #ifdef HAVE_ARES_GETNAMEINFO
1022 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1024 static PHP_FUNCTION(ares_getnameinfo
)
1026 zval
*rsrc
, *cb
= NULL
;
1028 php_ares_query
*query
;
1031 long flags
, port
= 0, family
= AF_INET
;
1032 struct sockaddr
*sa
;
1033 struct sockaddr_in
*in
;
1034 struct sockaddr_in6
*in6
;
1037 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rz!ls|ll", &rsrc
, &cb
, &flags
, &addr
, &addr_len
, &family
, &port
)) {
1040 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1042 if (cb
&& !IS_CALLABLE(cb
, 0, NULL
)) {
1043 PHP_ARES_CB_ERROR("second");
1050 in
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in
));
1051 in
->sin_family
= AF_INET
;
1052 in
->sin_port
= htons((unsigned short) port
);
1053 if (1 > inet_pton(in
->sin_family
, addr
, &in
->sin_addr
)) {
1054 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1057 sa
= (struct sockaddr
*) in
;
1060 in6
= ecalloc(1, sa_len
= sizeof(struct sockaddr_in6
));
1061 in6
->sin6_family
= AF_INET6
;
1062 in6
->sin6_port
= htons((unsigned short) port
);
1063 if (1 > inet_pton(in6
->sin6_family
, addr
, &in6
->sin6_addr
)) {
1064 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "inet_pton('%s') failed", addr
);
1067 sa
= (struct sockaddr
*) in6
;
1070 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Parameter family is neither AF_INET nor AF_INET6");
1075 if (Z_BVAL_P(return_value
)) {
1076 query
= php_ares_query_ctor(NULL
, PHP_ARES_CB_NINFO
, ares
, cb
);
1077 php_ares_query_rsrc(query
, return_value
);
1078 php_ares_query_pckt(query
, PHP_ARES_PCKT_NINFO
, flags
, addr
, addr_len
, family
, port
);
1079 ares_getnameinfo(ares
->channel
, sa
, sa_len
, flags
, php_ares_nameinfo_callback_func
, query
);
1086 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1087 Check a query for its result */
1088 static PHP_FUNCTION(ares_result
)
1090 zval
*rsrc
, *zerrno
= NULL
, *zerror
= NULL
;
1091 php_ares_query
*query
;
1093 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|zz", &rsrc
, &zerrno
, &zerror
)) {
1096 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1100 ZVAL_LONG(zerrno
, query
->error
);
1107 switch (query
->error
) {
1109 switch (query
->type
) {
1110 case PHP_ARES_CB_STD
:
1111 RETVAL_STRINGL(query
->result
.std
.buf
, query
->result
.std
.len
, 1);
1113 case PHP_ARES_CB_HOST
:
1114 object_init(return_value
);
1115 php_ares_hostent_to_struct(&query
->result
.host
, HASH_OF(return_value
));
1117 case PHP_ARES_CB_NINFO
:
1118 object_init(return_value
);
1119 add_property_string(return_value
, "node", query
->result
.ninfo
.node
? query
->result
.ninfo
.node
: "", 1);
1120 add_property_string(return_value
, "service", query
->result
.ninfo
.service
? query
->result
.ninfo
.service
: "", 1);
1129 #ifdef HAVE_OLD_ARES_STRERROR
1131 const char *__err
= ares_strerror(query
->error
, &__tmp
);
1132 ZVAL_STRING(zerror
, estrdup(__err
), 0);
1133 if (__tmp
) ares_free_errmem(__tmp
);
1135 ZVAL_STRING(zerror
, estrdup(ares_strerror(query
->error
)), 0);
1144 /* {{{ proto object ares_packet(resource query)
1145 Check a query for its question packet */
1146 static PHP_FUNCTION(ares_packet
)
1149 php_ares_query
*query
;
1151 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1154 ZEND_FETCH_RESOURCE(query
, php_ares_query
*, &rsrc
, -1, PHP_ARES_QUERY_LE_NAME
, le_ares_query
);
1156 object_init(return_value
);
1157 add_property_long(return_value
, "type", query
->packet
.type
);
1158 add_property_null(return_value
, "search");
1159 add_property_null(return_value
, "query");
1160 add_property_null(return_value
, "send");
1161 add_property_null(return_value
, "gethostbyname");
1162 add_property_null(return_value
, "gethostbyaddr");
1163 add_property_null(return_value
, "getnameinfo");
1164 MAKE_STD_ZVAL(prop
);
1166 switch (query
->packet
.type
) {
1167 case PHP_ARES_PCKT_SEARCH
:
1169 add_property_stringl(prop
, "name", query
->packet
.data
.search
.name
, query
->packet
.data
.search
.name_len
, 1);
1170 add_property_long(prop
, "type", query
->packet
.data
.search
.type
);
1171 add_property_long(prop
, "dnsclass", query
->packet
.data
.search
.dnsclass
);
1172 add_property_zval(return_value
, "search", prop
);
1175 case PHP_ARES_PCKT_QUERY
:
1177 add_property_stringl(prop
, "name", query
->packet
.data
.query
.name
, query
->packet
.data
.query
.name_len
, 1);
1178 add_property_long(prop
, "type", query
->packet
.data
.query
.type
);
1179 add_property_long(prop
, "dnsclass", query
->packet
.data
.query
.dnsclass
);
1180 add_property_zval(return_value
, "query", prop
);
1183 case PHP_ARES_PCKT_SEND
:
1184 ZVAL_STRINGL(prop
, query
->packet
.data
.send
.buf
, query
->packet
.data
.send
.len
, 1);
1185 add_property_zval(return_value
, "send", prop
);
1188 case PHP_ARES_PCKT_HNAME
:
1190 add_property_stringl(prop
, "name", query
->packet
.data
.hname
.name
, query
->packet
.data
.hname
.name_len
, 1);
1191 add_property_long(prop
, "family", query
->packet
.data
.hname
.family
);
1192 add_property_zval(return_value
, "gethostbyname", prop
);
1195 case PHP_ARES_PCKT_HADDR
:
1197 add_property_stringl(prop
, "addr", query
->packet
.data
.haddr
.addr
, query
->packet
.data
.haddr
.addr_len
, 1);
1198 add_property_long(prop
, "family", query
->packet
.data
.haddr
.family
);
1199 add_property_zval(return_value
, "gethostbyaddr", prop
);
1202 case PHP_ARES_PCKT_NINFO
:
1204 add_property_long(prop
, "flags", query
->packet
.data
.ninfo
.flags
);
1205 add_property_stringl(prop
, "addr", query
->packet
.data
.ninfo
.addr
, query
->packet
.data
.ninfo
.addr_len
, 1);
1206 add_property_long(prop
, "family", query
->packet
.data
.ninfo
.family
);
1207 add_property_long(prop
, "port", query
->packet
.data
.ninfo
.port
);
1208 add_property_zval(return_value
, "getnameinfo", prop
);
1212 zval_ptr_dtor(&prop
);
1216 #ifdef HAVE_ARES_CANCEL
1217 /* {{{ proto void ares_cancel(resource ares)
1218 Cancel pending queries */
1219 static PHP_FUNCTION(ares_cancel
)
1224 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &rsrc
)) {
1225 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1226 ares_cancel(ares
->channel
);
1232 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1233 Process all pending queries */
1234 static PHP_FUNCTION(ares_process_all
)
1238 long max_timeout
= -1;
1240 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1243 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1245 while (php_ares_process(ares
, max_timeout
));
1249 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1250 Process once and return whether it should be called again */
1251 static PHP_FUNCTION(ares_process_once
)
1255 long max_timeout
= -1;
1257 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1260 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1262 RETVAL_BOOL(php_ares_process(ares
, max_timeout
));
1266 /* {{{ proto void ares_process(resource ares, array read, array write)
1268 static PHP_FUNCTION(ares_process
)
1270 zval
*rsrc
, *read
= NULL
, *write
= NULL
;
1274 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|a!a!", &rsrc
, &read
, &write
)) {
1277 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1282 php_ares_extract_fds(read
, write
, &R
, &W
);
1283 ares_process(ares
->channel
, &R
, &W
);
1287 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1289 static PHP_FUNCTION(ares_select
)
1291 zval
*read
= NULL
, *write
= NULL
;
1297 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "aal", &read
, &write
, &timeout
)) {
1302 tv
.tv_sec
= timeout
/ 1000;
1303 tv
.tv_usec
= timeout
% (timeout
* 1000);
1312 nfds
= php_ares_extract_fds(read
, write
, &R
, &W
);
1313 if (-1 < select(nfds
, &R
, &W
, NULL
, &tv
)) {
1314 zend_hash_clean(Z_ARRVAL_P(read
));
1315 zend_hash_clean(Z_ARRVAL_P(write
));
1316 php_ares_publish_fds(&R
, &W
, read
, write
);
1323 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1324 Get suggested select timeout in ms */
1325 static PHP_FUNCTION(ares_timeout
)
1328 long max_timeout
= -1;
1329 struct timeval tv
, *tvptr
;
1332 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &rsrc
, &max_timeout
)) {
1335 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1337 if ((tvptr
= php_ares_timeout(ares
, max_timeout
, &tv
))) {
1338 RETURN_LONG(tvptr
->tv_sec
* 1000 + tvptr
->tv_usec
/ 1000);
1344 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1345 Get file descriptors */
1346 static PHP_FUNCTION(ares_fds
)
1348 zval
*rsrc
, *read
, *write
;
1352 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rzz", &rsrc
, &read
, &write
)) {
1355 ZEND_FETCH_RESOURCE(ares
, php_ares
*, &rsrc
, -1, PHP_ARES_LE_NAME
, le_ares
);
1364 ares_fds(ares
->channel
, &R
, &W
);
1365 RETVAL_LONG(php_ares_publish_fds(&R
, &W
, read
, write
));
1369 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor
)
1371 php_ares
*ares
= (php_ares
*) rsrc
->ptr
;
1373 ares_destroy(ares
->channel
);
1374 zend_llist_destroy(&ares
->queries
);
1375 php_ares_options_dtor(&ares
->options
);
1379 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor
)
1381 php_ares_query
*query
= (php_ares_query
*) rsrc
->ptr
;
1383 php_ares_query_dtor(query
);
1387 /* {{{ PHP_MINIT_FUNCTION */
1388 static PHP_MINIT_FUNCTION(ares
)
1390 #ifdef HAVE_ARES_VERSION
1391 int ares_version_num
;
1392 ares_version(&ares_version_num
);
1394 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num
, CONST_PERSISTENT
|CONST_CS
);
1397 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS
, CONST_PERSISTENT
|CONST_CS
);
1398 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA
, CONST_PERSISTENT
|CONST_CS
);
1399 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR
, CONST_PERSISTENT
|CONST_CS
);
1400 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL
, CONST_PERSISTENT
|CONST_CS
);
1401 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND
, CONST_PERSISTENT
|CONST_CS
);
1402 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP
, CONST_PERSISTENT
|CONST_CS
);
1403 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1404 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY
, CONST_PERSISTENT
|CONST_CS
);
1405 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME
, CONST_PERSISTENT
|CONST_CS
);
1406 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY
, CONST_PERSISTENT
|CONST_CS
);
1407 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP
, CONST_PERSISTENT
|CONST_CS
);
1408 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED
, CONST_PERSISTENT
|CONST_CS
);
1409 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT
, CONST_PERSISTENT
|CONST_CS
);
1410 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF
, CONST_PERSISTENT
|CONST_CS
);
1411 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE
, CONST_PERSISTENT
|CONST_CS
);
1412 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM
, CONST_PERSISTENT
|CONST_CS
);
1413 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION
, CONST_PERSISTENT
|CONST_CS
);
1415 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR
, CONST_PERSISTENT
|CONST_CS
);
1417 #ifdef ARES_EBADFLAGS
1418 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS
, CONST_PERSISTENT
|CONST_CS
);
1421 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME
, CONST_PERSISTENT
|CONST_CS
);
1423 #ifdef ARES_EBADHINTS
1424 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS
, CONST_PERSISTENT
|CONST_CS
);
1427 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC
, CONST_PERSISTENT
|CONST_CS
);
1428 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY
, CONST_PERSISTENT
|CONST_CS
);
1429 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC
, CONST_PERSISTENT
|CONST_CS
);
1430 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE
, CONST_PERSISTENT
|CONST_CS
);
1431 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN
, CONST_PERSISTENT
|CONST_CS
);
1432 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH
, CONST_PERSISTENT
|CONST_CS
);
1433 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES
, CONST_PERSISTENT
|CONST_CS
);
1434 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP
, CONST_PERSISTENT
|CONST_CS
);
1437 * Address Family Constants
1439 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET
, CONST_PERSISTENT
|CONST_CS
);
1440 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6
, CONST_PERSISTENT
|CONST_CS
);
1443 * Name Info constants
1445 #ifdef ARES_NI_NOFQDN
1446 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN
, CONST_PERSISTENT
|CONST_CS
);
1448 #ifdef ARES_NI_NUMERICHOST
1449 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
1451 #ifdef ARES_NI_NAMEREQD
1452 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD
, CONST_PERSISTENT
|CONST_CS
);
1454 #ifdef ARES_NI_NUMERICSERV
1455 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
1457 #ifdef ARES_NI_DGRAM
1458 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM
, CONST_PERSISTENT
|CONST_CS
);
1461 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP
, CONST_PERSISTENT
|CONST_CS
);
1464 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP
, CONST_PERSISTENT
|CONST_CS
);
1467 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP
, CONST_PERSISTENT
|CONST_CS
);
1470 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP
, CONST_PERSISTENT
|CONST_CS
);
1472 #ifdef ARES_NI_NUMERICSCOPE
1473 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE
, CONST_PERSISTENT
|CONST_CS
);
1475 #ifdef ARES_NI_LOOKUPHOST
1476 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST
, CONST_PERSISTENT
|CONST_CS
);
1478 #ifdef ARES_NI_LOOKUPSERVICE
1479 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE
, CONST_PERSISTENT
|CONST_CS
);
1482 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN
, CONST_PERSISTENT
|CONST_CS
);
1484 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1485 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
1487 #ifdef ARES_NI_IDN_USE_STD
1488 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
1492 * Address Info constants
1494 #ifdef ARES_AI_CANONNAME
1495 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME
, CONST_PERSISTENT
|CONST_CS
);
1497 #ifdef ARES_AI_NUMERICHOST
1498 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST
, CONST_PERSISTENT
|CONST_CS
);
1500 #ifdef ARES_AI_PASSIVE
1501 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE
, CONST_PERSISTENT
|CONST_CS
);
1503 #ifdef ARES_AI_NUMERICSERV
1504 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV
, CONST_PERSISTENT
|CONST_CS
);
1507 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V
, CONST_PERSISTENT
|CONST_CS
);
1510 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL
, CONST_PERSISTENT
|CONST_CS
);
1512 #ifdef ARES_AI_ADDRCONFIG
1513 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG
, CONST_PERSISTENT
|CONST_CS
);
1516 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN
, CONST_PERSISTENT
|CONST_CS
);
1518 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1519 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED
, CONST_PERSISTENT
|CONST_CS
);
1521 #ifdef ARES_AI_IDN_USE_STD
1522 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD
, CONST_PERSISTENT
|CONST_CS
);
1524 #ifdef ARES_AI_CANONIDN
1525 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN
, CONST_PERSISTENT
|CONST_CS
);
1528 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK
, CONST_PERSISTENT
|CONST_CS
);
1530 #ifdef ARES_GETSOCK_MAXNUM
1531 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM
, CONST_PERSISTENT
|CONST_CS
);
1535 * ns_t (type) constants (arpa/nameser.h)
1538 /* (1) Host address. */
1539 REGISTER_LONG_CONSTANT("ARES_T_A", ns_t_a
, CONST_CS
|CONST_PERSISTENT
);
1540 /* (2) Authoritative server. */
1541 REGISTER_LONG_CONSTANT("ARES_T_NS", ns_t_ns
, CONST_CS
|CONST_PERSISTENT
);
1542 /* (3) Mail destination. */
1543 REGISTER_LONG_CONSTANT("ARES_T_MD", ns_t_md
, CONST_CS
|CONST_PERSISTENT
);
1544 /* (4) Mail forwarder. */
1545 REGISTER_LONG_CONSTANT("ARES_T_MF", ns_t_mf
, CONST_CS
|CONST_PERSISTENT
);
1546 /* (5) Canonical name. */
1547 REGISTER_LONG_CONSTANT("ARES_T_CNAME", ns_t_cname
, CONST_CS
|CONST_PERSISTENT
);
1548 /* (6) Start of authority zone. */
1549 REGISTER_LONG_CONSTANT("ARES_T_SOA", ns_t_soa
, CONST_CS
|CONST_PERSISTENT
);
1550 /* (7) Mailbox domain name. */
1551 REGISTER_LONG_CONSTANT("ARES_T_MB", ns_t_mb
, CONST_CS
|CONST_PERSISTENT
);
1552 /* (8) Mail group member. */
1553 REGISTER_LONG_CONSTANT("ARES_T_MG", ns_t_mg
, CONST_CS
|CONST_PERSISTENT
);
1554 /* (9) Mail rename name. */
1555 REGISTER_LONG_CONSTANT("ARES_T_MR", ns_t_mr
, CONST_CS
|CONST_PERSISTENT
);
1556 /* (10) Null resource record. */
1557 REGISTER_LONG_CONSTANT("ARES_T_NULL", ns_t_null
, CONST_CS
|CONST_PERSISTENT
);
1558 /* (11) Well known service. */
1559 REGISTER_LONG_CONSTANT("ARES_T_WKS", ns_t_wks
, CONST_CS
|CONST_PERSISTENT
);
1560 /* (12) Domain name pointer. */
1561 REGISTER_LONG_CONSTANT("ARES_T_PTR", ns_t_ptr
, CONST_CS
|CONST_PERSISTENT
);
1562 /* (13) Host information. */
1563 REGISTER_LONG_CONSTANT("ARES_T_HINFO", ns_t_hinfo
, CONST_CS
|CONST_PERSISTENT
);
1564 /* (14) Mailbox information. */
1565 REGISTER_LONG_CONSTANT("ARES_T_MINFO", ns_t_minfo
, CONST_CS
|CONST_PERSISTENT
);
1566 /* (15) Mail routing information. */
1567 REGISTER_LONG_CONSTANT("ARES_T_MX", ns_t_mx
, CONST_CS
|CONST_PERSISTENT
);
1568 /* (16) Text strings. */
1569 REGISTER_LONG_CONSTANT("ARES_T_TXT", ns_t_txt
, CONST_CS
|CONST_PERSISTENT
);
1570 /* (17) Responsible person. */
1571 REGISTER_LONG_CONSTANT("ARES_T_RP", ns_t_rp
, CONST_CS
|CONST_PERSISTENT
);
1572 /* (18) AFS cell database. */
1573 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", ns_t_afsdb
, CONST_CS
|CONST_PERSISTENT
);
1574 /* (19) X_25 calling address. */
1575 REGISTER_LONG_CONSTANT("ARES_T_X25", ns_t_x25
, CONST_CS
|CONST_PERSISTENT
);
1576 /* (20) ISDN calling address. */
1577 REGISTER_LONG_CONSTANT("ARES_T_ISDN", ns_t_isdn
, CONST_CS
|CONST_PERSISTENT
);
1579 REGISTER_LONG_CONSTANT("ARES_T_RT", ns_t_rt
, CONST_CS
|CONST_PERSISTENT
);
1580 /* (22) NSAP address. */
1581 REGISTER_LONG_CONSTANT("ARES_T_NSAP", ns_t_nsap
, CONST_CS
|CONST_PERSISTENT
);
1582 /* (23) Reverse NSAP lookup (deprecated). */
1583 /* REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", ns_t_nsap_ptr, CONST_CS|CONST_PERSISTENT); */
1584 /* (24) Security signature. */
1585 REGISTER_LONG_CONSTANT("ARES_T_SIG", ns_t_sig
, CONST_CS
|CONST_PERSISTENT
);
1586 /* (25) Security key. */
1587 REGISTER_LONG_CONSTANT("ARES_T_KEY", ns_t_key
, CONST_CS
|CONST_PERSISTENT
);
1588 /* (26) X.400 mail mapping. */
1589 REGISTER_LONG_CONSTANT("ARES_T_PX", ns_t_px
, CONST_CS
|CONST_PERSISTENT
);
1590 /* (27) Geographical position (withdrawn). */
1591 /* REGISTER_LONG_CONSTANT("ARES_T_GPOS", ns_t_gpos, CONST_CS|CONST_PERSISTENT); */
1592 /* (28) Ip6 Address. */
1593 REGISTER_LONG_CONSTANT("ARES_T_AAAA", ns_t_aaaa
, CONST_CS
|CONST_PERSISTENT
);
1594 /* (29) Location Information. */
1595 REGISTER_LONG_CONSTANT("ARES_T_LOC", ns_t_loc
, CONST_CS
|CONST_PERSISTENT
);
1596 /* (30) Next domain (security). */
1597 REGISTER_LONG_CONSTANT("ARES_T_NXT", ns_t_nxt
, CONST_CS
|CONST_PERSISTENT
);
1598 /* (31) Endpoint identifier. */
1599 REGISTER_LONG_CONSTANT("ARES_T_EID", ns_t_eid
, CONST_CS
|CONST_PERSISTENT
);
1600 /* (32) Nimrod Locator. */
1601 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", ns_t_nimloc
, CONST_CS
|CONST_PERSISTENT
);
1602 /* (33) Server Selection. */
1603 REGISTER_LONG_CONSTANT("ARES_T_SRV", ns_t_srv
, CONST_CS
|CONST_PERSISTENT
);
1604 /* (34) ATM Address */
1605 REGISTER_LONG_CONSTANT("ARES_T_ATMA", ns_t_atma
, CONST_CS
|CONST_PERSISTENT
);
1606 /* (35) Naming Authority PoinTeR */
1607 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", ns_t_naptr
, CONST_CS
|CONST_PERSISTENT
);
1608 /* (36) Key Exchange */
1609 REGISTER_LONG_CONSTANT("ARES_T_KX", ns_t_kx
, CONST_CS
|CONST_PERSISTENT
);
1610 /* (37) Certification record */
1611 REGISTER_LONG_CONSTANT("ARES_T_CERT", ns_t_cert
, CONST_CS
|CONST_PERSISTENT
);
1612 /* (38) IPv6 address (deprecates AAAA) */
1613 REGISTER_LONG_CONSTANT("ARES_T_A6", ns_t_a6
, CONST_CS
|CONST_PERSISTENT
);
1614 /* (39) Non-terminal DNAME (for IPv6) */
1615 REGISTER_LONG_CONSTANT("ARES_T_DNAME", ns_t_dname
, CONST_CS
|CONST_PERSISTENT
);
1616 /* (40) Kitchen sink (experimentatl) */
1617 REGISTER_LONG_CONSTANT("ARES_T_SINK", ns_t_sink
, CONST_CS
|CONST_PERSISTENT
);
1618 /* (41) EDNS0 option (meta-RR) */
1619 REGISTER_LONG_CONSTANT("ARES_T_OPT", ns_t_opt
, CONST_CS
|CONST_PERSISTENT
);
1620 /* (250) Transaction signature. */
1621 REGISTER_LONG_CONSTANT("ARES_T_TSIG", ns_t_tsig
, CONST_CS
|CONST_PERSISTENT
);
1622 /* (251) Incremental zone transfer. */
1623 REGISTER_LONG_CONSTANT("ARES_T_IXFR", ns_t_ixfr
, CONST_CS
|CONST_PERSISTENT
);
1624 /* (252) Transfer zone of authority. */
1625 REGISTER_LONG_CONSTANT("ARES_T_AXFR", ns_t_axfr
, CONST_CS
|CONST_PERSISTENT
);
1626 /* (253) Transfer mailbox records. */
1627 REGISTER_LONG_CONSTANT("ARES_T_MAILB", ns_t_mailb
, CONST_CS
|CONST_PERSISTENT
);
1628 /* (254) Transfer mail agent records. */
1629 REGISTER_LONG_CONSTANT("ARES_T_MAILA", ns_t_maila
, CONST_CS
|CONST_PERSISTENT
);
1630 /* (255) Wildcard match. */
1631 REGISTER_LONG_CONSTANT("ARES_T_ANY", ns_t_any
, CONST_CS
|CONST_PERSISTENT
);
1634 * ns_c (dnsclass) constants (arpa/nameser.h)
1638 REGISTER_LONG_CONSTANT("ARES_C_IN", ns_c_in
, CONST_CS
|CONST_PERSISTENT
);
1639 /* (2) unallocated/unsupported. */
1640 /* REGISTER_LONG_CONSTANT("ARES_C_2", ns_c_2, CONST_CS|CONST_PERSISTENT); */
1641 /* (3) MIT Chaos-net. */
1642 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", ns_c_chaos
, CONST_CS
|CONST_PERSISTENT
);
1643 /* (4) MIT Hesiod. */
1644 REGISTER_LONG_CONSTANT("ARES_C_HS", ns_c_hs
, CONST_CS
|CONST_PERSISTENT
);
1645 /* (254) for prereq. sections in update requests */
1646 /* REGISTER_LONG_CONSTANT("ARES_C_NONE", ns_c_none, CONST_CS|CONST_PERSISTENT); */
1647 /* (255) Wildcard match. */
1648 REGISTER_LONG_CONSTANT("ARES_C_ANY", ns_c_any
, CONST_CS
|CONST_PERSISTENT
);
1650 le_ares
= zend_register_list_destructors_ex(php_ares_le_dtor
, NULL
, PHP_ARES_LE_NAME
, module_number
);
1651 le_ares_query
= zend_register_list_destructors_ex(php_ares_query_le_dtor
, NULL
, PHP_ARES_QUERY_LE_NAME
, module_number
);
1657 /* {{{ PHP_MINFO_FUNCTION */
1658 static PHP_MINFO_FUNCTION(ares
)
1660 php_info_print_table_start();
1661 php_info_print_table_header(2, "AsyncResolver support", "enabled");
1662 php_info_print_table_row(2, "Version", PHP_ARES_VERSION
);
1663 php_info_print_table_end();
1665 php_info_print_table_start();
1666 php_info_print_table_header(3, "Used Library", "compiled", "linked");
1667 php_info_print_table_row(3,
1669 #ifdef ARES_VERSION_STR
1674 #ifdef HAVE_ARES_VERSION
1680 php_info_print_table_end();
1684 #ifdef ZEND_ENGINE_2
1685 ZEND_BEGIN_ARG_INFO(ai_ares_select
, 0)
1686 ZEND_ARG_PASS_INFO(1)
1687 ZEND_ARG_PASS_INFO(1)
1688 ZEND_ARG_PASS_INFO(0)
1689 ZEND_END_ARG_INFO();
1691 ZEND_BEGIN_ARG_INFO(ai_ares_result
, 0)
1692 ZEND_ARG_PASS_INFO(0)
1693 ZEND_ARG_PASS_INFO(1)
1694 ZEND_ARG_PASS_INFO(1)
1695 ZEND_END_ARG_INFO();
1697 ZEND_BEGIN_ARG_INFO(ai_ares_fds
, 0)
1698 ZEND_ARG_PASS_INFO(0)
1699 ZEND_ARG_PASS_INFO(1)
1700 ZEND_ARG_PASS_INFO(1)
1701 ZEND_END_ARG_INFO();
1703 static unsigned char ai_ares_select
[] = {3, BYREF_FORCE
, BYREF_FORCE
, BYREF_NONE
};
1704 static unsigned char ai_ares_result
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
1705 static unsigned char ai_ares_fds
[] = {4, BYREF_NONE
, BYREF_FORCE
, BYREF_FORCE
};
1708 /* {{{ ares_functions[] */
1709 zend_function_entry ares_functions
[] = {
1710 #ifdef HAVE_ARES_VERSION
1711 PHP_FE(ares_version
, NULL
)
1713 PHP_FE(ares_init
, NULL
)
1714 PHP_FE(ares_destroy
, NULL
)
1715 PHP_FE(ares_strerror
, NULL
)
1716 #ifdef HAVE_ARES_CANCEL
1717 PHP_FE(ares_cancel
, NULL
)
1719 PHP_FE(ares_search
, NULL
)
1720 PHP_FE(ares_query
, NULL
)
1721 PHP_FE(ares_send
, NULL
)
1722 PHP_FE(ares_mkquery
, NULL
)
1723 PHP_FE(ares_gethostbyname
, NULL
)
1724 PHP_FE(ares_gethostbyaddr
, NULL
)
1725 #ifdef HAVE_ARES_GETNAMEINFO
1726 PHP_FE(ares_getnameinfo
, NULL
)
1728 PHP_FE(ares_result
, ai_ares_result
)
1729 PHP_FE(ares_packet
, NULL
)
1730 PHP_FE(ares_process_all
, NULL
)
1731 PHP_FE(ares_process_once
, NULL
)
1732 PHP_FE(ares_process
, NULL
)
1733 PHP_FE(ares_select
, ai_ares_select
)
1734 PHP_FE(ares_fds
, ai_ares_fds
)
1735 PHP_FE(ares_timeout
, NULL
)
1740 /* {{{ ares_module_entry */
1741 zend_module_entry ares_module_entry
= {
1742 STANDARD_MODULE_HEADER
,
1751 STANDARD_MODULE_PROPERTIES
1755 #ifdef COMPILE_DL_ARES
1756 ZEND_GET_MODULE(ares
)
1764 * vim600: noet sw=4 ts=4 fdm=marker
1765 * vim<600: noet sw=4 ts=4