fix php-5.3 incomatibility and several typos
[m6w6/ext-ares] / ares.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: ares |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2006, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "php.h"
20 #include "php_ini.h"
21 #include "ext/standard/info.h"
22 #include "php_ares.h"
23
24 #include <ares.h>
25 #ifdef HAVE_ARES_VERSION
26 # include <ares_version.h>
27 #endif
28 #ifdef HAVE_NETDB_H
29 # include <netdb.h>
30 #endif
31 #ifdef HAVE_UNISTD_H
32 # include <unistd.h>
33 #endif
34 #ifdef HAVE_ARPA_INET_H
35 # include <arpa/inet.h>
36 #endif
37 #ifdef HAVE_ARPA_NAMESER_H
38 # include <arpa/nameser.h>
39 #endif
40
41 #define local inline
42
43 #ifndef ZEND_ENGINE_2
44 # define IS_CALLABLE(a,b,c) 1
45 # ifndef ZTS
46 # undef TSRMLS_SET_CTX
47 # define TSRMLS_SET_CTX
48 # undef TSRMLS_FETCH_FROM_CTX
49 # define TSRMLS_FETCH_FROM_CTX
50 # endif
51 #endif
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)
55 #else
56 # define ADDREF(z) ZVAL_ADDREF(z)
57 # define IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
58 #endif
59
60 #define PHP_ARES_LE_NAME "AsyncResolver"
61 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
62 static int le_ares;
63 static int le_ares_query;
64
65 #ifdef HAVE_OLD_ARES_STRERROR
66 # define PHP_ARES_ERROR(err) { \
67 char *__tmp = NULL; \
68 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err, &__tmp)); \
69 if (__tmp) ares_free_errmem(__tmp); \
70 }
71 #else
72 # define PHP_ARES_ERROR(err) \
73 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
74 #endif
75
76 #define RETURN_ARES_ERROR(err) \
77 PHP_ARES_ERROR(err); \
78 RETURN_FALSE
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); \
83 RETURN_FALSE
84
85 /* {{{ typedefs */
86 typedef struct _php_ares_options {
87 struct ares_options strct;
88 int flags;
89 } php_ares_options;
90
91 typedef struct _php_ares {
92 ares_channel channel;
93 php_ares_options options;
94 zend_llist queries;
95 void ***tsrm_ls;
96 unsigned in_callback:1;
97 unsigned reserved:31;
98 } php_ares;
99
100 typedef enum _php_ares_query_type {
101 PHP_ARES_CB_STD,
102 PHP_ARES_CB_HOST,
103 PHP_ARES_CB_NINFO,
104 } php_ares_query_type;
105
106 typedef enum _php_ares_query_packet_type {
107 PHP_ARES_PCKT_SEARCH,
108 PHP_ARES_PCKT_QUERY,
109 PHP_ARES_PCKT_SEND,
110 PHP_ARES_PCKT_HNAME,
111 PHP_ARES_PCKT_HADDR,
112 PHP_ARES_PCKT_NINFO,
113 } php_ares_query_packet_type;
114
115 typedef union _php_ares_query_packet_data {
116 struct {
117 char *name;
118 int name_len;
119 long type;
120 long dnsclass;
121 } search;
122 struct {
123 char *name;
124 int name_len;
125 long type;
126 long dnsclass;
127 } query;
128 struct {
129 char *buf;
130 int len;
131 } send;
132 struct {
133 char *name;
134 int name_len;
135 long family;
136 } hname;
137 struct {
138 char *addr;
139 int addr_len;
140 long family;
141 } haddr;
142 struct {
143 char *addr;
144 int addr_len;
145 long port;
146 long family;
147 long flags;
148 } ninfo;
149 } php_ares_query_packet_data;
150
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;
155
156 typedef union _php_ares_query_result {
157 struct {
158 char *buf;
159 int len;
160 } std;
161 struct hostent host;
162 struct {
163 char *service;
164 char *node;
165 } ninfo;
166 } php_ares_query_result;
167
168 typedef struct _php_ares_query {
169 int id;
170 int error;
171 php_ares *ares;
172 zval *callback;
173 php_ares_query_type type;
174 php_ares_query_packet packet;
175 php_ares_query_result result;
176 } php_ares_query;
177 /* }}} */
178
179 local struct hostent *php_ares_hostent_ctor(struct hostent *host) /* {{{ */
180 {
181 if (!host) {
182 host = emalloc(sizeof(struct hostent));
183 }
184 memset(host, 0, sizeof(struct hostent));
185
186 return host;
187 }
188 /* }}} */
189
190 local void php_ares_hostent_copy(struct hostent *from, struct hostent *to) /* {{{ */
191 {
192 int i, c;
193 char **ptr;
194
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]);
201 }
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);
207 }
208 }
209 /* }}} */
210
211 local void php_ares_hostent_to_struct(struct hostent *hostent, HashTable *ht) /* {{{ */
212 {
213 zval array, *tmp;
214 char **ptr;
215
216 INIT_PZVAL(&array);
217 Z_TYPE(array) = IS_ARRAY;
218 Z_ARRVAL(array) = ht;
219
220 if (hostent) {
221 add_assoc_string(&array, "name", hostent->h_name, 1);
222
223 MAKE_STD_ZVAL(tmp);
224 array_init(tmp);
225 if (hostent->h_aliases) {
226 for (ptr = hostent->h_aliases; *ptr; ++ptr) {
227 add_next_index_string(tmp, *ptr, 1);
228 }
229 }
230 add_assoc_zval(&array, "aliases", tmp);
231 add_assoc_long(&array, "addrtype", hostent->h_addrtype);
232
233 MAKE_STD_ZVAL(tmp);
234 array_init(tmp);
235 if (hostent->h_addr_list) {
236 for (ptr = hostent->h_addr_list; *ptr; ++ptr) {
237 char name[64] = {0};
238
239 if (inet_ntop(hostent->h_addrtype, *ptr, name, sizeof(name)-1)) {
240 add_next_index_string(tmp, name, 1);
241 }
242 }
243 }
244 add_assoc_zval(&array, "addrlist", tmp);
245 }
246 }
247 /* }}} */
248
249 local void php_ares_hostent_dtor(struct hostent *host) /* {{{ */
250 {
251 char **ptr;
252
253 STR_FREE(host->h_name);
254 if (host->h_aliases) {
255 for (ptr = host->h_aliases; *ptr; ++ptr) {
256 efree(*ptr);
257 }
258 efree(host->h_aliases);
259 }
260 if (host->h_addr_list) {
261 for (ptr = host->h_addr_list; *ptr; ++ptr) {
262 efree(*ptr);
263 }
264 efree(host->h_addr_list);
265 }
266 memset(host, 0, sizeof(struct hostent));
267 }
268 /* }}} */
269
270 local void php_ares_hostent_free(struct hostent **host) /* {{{ */
271 {
272 php_ares_hostent_dtor(*host);
273 efree(*host);
274 *host = NULL;
275 }
276 /* }}} */
277
278 local php_ares_query *php_ares_query_ctor(php_ares_query *query, php_ares_query_type type, php_ares *ares, zval *callback) /* {{{ */
279 {
280 if (!query) {
281 query = emalloc(sizeof(php_ares_query));
282 }
283 memset(query, 0, sizeof(php_ares_query));
284
285 query->ares = ares;
286 query->type = type;
287 query->error = -1;
288
289 if (callback) {
290 ADDREF(callback);
291 query->callback = callback;
292 }
293
294 return query;
295 }
296 /* }}} */
297
298 local void php_ares_query_rsrc(php_ares_query *query, zval *return_value) /* {{{ */
299 {
300 TSRMLS_FETCH_FROM_CTX(query->ares->tsrm_ls);
301
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);
306 }
307 /* }}} */
308
309 local void php_ares_query_pckt(php_ares_query *query, php_ares_query_packet_type type, ...)
310 {
311 va_list argv;
312 char *buf;
313 int len;
314
315 va_start(argv, type);
316
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);
325 break;
326
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);
334 break;
335
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;
341 break;
342
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);
349 break;
350
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);
357 break;
358
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);
367 break;
368 }
369
370 va_end(argv);
371 }
372
373 local void php_ares_query_dtor(php_ares_query *query) /* {{{ */
374 {
375 struct php_ares_query_packet_buf {char *buf;} *packet;
376
377 packet = (struct php_ares_query_packet_buf *) &query->packet.data;
378 if (packet->buf) {
379 efree(packet->buf);
380 }
381 switch (query->type) {
382 case PHP_ARES_CB_STD:
383 STR_FREE(query->result.std.buf);
384 break;
385 case PHP_ARES_CB_HOST:
386 php_ares_hostent_dtor(&query->result.host);
387 break;
388 case PHP_ARES_CB_NINFO:
389 STR_FREE(query->result.ninfo.service);
390 STR_FREE(query->result.ninfo.node);
391 break;
392 }
393 if (query->callback) {
394 zval_ptr_dtor(&query->callback);
395 }
396 memset(query, 0, sizeof(php_ares_query));
397 }
398 /* }}} */
399
400 local void php_ares_query_free(php_ares_query **query) /* {{{ */
401 {
402 php_ares_query_dtor(*query);
403 efree(*query);
404 *query = NULL;
405 }
406 /* }}} */
407
408 local php_ares_options *php_ares_options_ctor(php_ares_options *options, HashTable *ht) /* {{{ */
409 {
410 int i;
411 zval **opt, **entry;
412
413 if (!options) {
414 options = emalloc(sizeof(php_ares_options));
415 }
416 memset(options, 0, sizeof(php_ares_options));
417
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);
422 }
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);
426 }
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);
430 }
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);
434 }
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));
438 }
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));
442 }
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++]);
450 }
451 }
452 if (options->strct.nservers) {
453 options->flags |= ARES_OPT_SERVERS;
454 }
455 }
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));
463 }
464 }
465 if (options->strct.ndomains) {
466 options->flags |= ARES_OPT_DOMAINS;
467 }
468 }
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));
472 }
473 }
474
475 return options;
476 }
477 /* }}} */
478
479 local void php_ares_options_dtor(php_ares_options *options) /* {{{ */
480 {
481 int i;
482
483 if (options->strct.servers) {
484 efree(options->strct.servers);
485 }
486
487 if (options->strct.domains) {
488 for (i = 0; i < options->strct.ndomains; ++i) {
489 efree(options->strct.domains[i]);
490 }
491 efree(options->strct.domains);
492 }
493
494 STR_FREE(options->strct.lookups);
495
496 memset(options, 0, sizeof(php_ares_options));
497 }
498 /* }}} */
499
500 local void php_ares_options_free(php_ares_options **options) /* {{{ */
501 {
502 php_ares_options_dtor(*options);
503 efree(*options);
504 *options = NULL;
505 }
506 /* }}} */
507
508 /* {{{ callbacks */
509 static void php_ares_callback_func_old(void *aq, int status, unsigned char *abuf, int alen)
510 {
511 php_ares_query *q = (php_ares_query *) aq;
512 zval *params[3], *retval;
513 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
514
515 q->error = status;
516 if (abuf) {
517 q->result.std.buf = estrndup((char *) abuf, alen);
518 q->result.std.len = alen;
519 }
520
521 if (q->callback) {
522 MAKE_STD_ZVAL(retval);
523 MAKE_STD_ZVAL(params[0]);
524 MAKE_STD_ZVAL(params[1]);
525 MAKE_STD_ZVAL(params[2]);
526 ZVAL_NULL(retval);
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);
532
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;
536
537 zval_ptr_dtor(&retval);
538 zval_ptr_dtor(&params[0]);
539 zval_ptr_dtor(&params[1]);
540 zval_ptr_dtor(&params[2]);
541 }
542 }
543
544 static void php_ares_host_callback_func_old(void *aq, int status, struct hostent *hostent)
545 {
546 php_ares_query *q = (php_ares_query *) aq;
547 zval *params[3], *retval;
548 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
549
550 q->error = status;
551 if (hostent) {
552 php_ares_hostent_copy(hostent, &q->result.host);
553 }
554
555 if (q->callback) {
556 MAKE_STD_ZVAL(retval);
557 MAKE_STD_ZVAL(params[0]);
558 MAKE_STD_ZVAL(params[1]);
559 MAKE_STD_ZVAL(params[2]);
560 ZVAL_NULL(retval);
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]));
567
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;
571
572 zval_ptr_dtor(&retval);
573 zval_ptr_dtor(&params[0]);
574 zval_ptr_dtor(&params[1]);
575 zval_ptr_dtor(&params[2]);
576 }
577 }
578
579 #ifdef HAVE_ARES_GETNAMEINFO
580 static void php_ares_nameinfo_callback_func_old(void *aq, int status, char *node, char *service)
581 {
582 php_ares_query *q = (php_ares_query *) aq;
583 zval *params[4], *retval;
584 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
585
586 q->error = status;
587 if (node) {
588 q->result.ninfo.node = estrdup(node);
589 }
590 if (service) {
591 q->result.ninfo.service = estrdup(service);
592 }
593
594 if (q->callback) {
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]);
600 ZVAL_NULL(retval);
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);
605 if (node) {
606 ZVAL_STRING(params[2], node, 1);
607 } else {
608 ZVAL_NULL(params[2]);
609 }
610 if (service) {
611 ZVAL_STRING(params[3], service, 1);
612 } else {
613 ZVAL_NULL(params[3]);
614 }
615
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;
619
620 zval_ptr_dtor(&retval);
621 zval_ptr_dtor(&params[0]);
622 zval_ptr_dtor(&params[1]);
623 zval_ptr_dtor(&params[2]);
624 zval_ptr_dtor(&params[3]);
625 }
626 }
627 #endif
628
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)
632 {
633 php_ares_callback_func_old(aq, status, abuf, alen);
634 }
635
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)
638 {
639 php_ares_host_callback_func_old(aq, status, hostent);
640 }
641
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)
645 {
646 php_ares_nameinfo_callback_func_old(aq, status, node, service);
647 }
648 # endif
649
650 #else
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
655 # endif
656 #endif
657 /* }}} */
658
659 local struct timeval *php_ares_timeout(php_ares *ares, long max_timeout, struct timeval *tv_buf) /* {{{ */
660 {
661 struct timeval maxtv;
662
663 if (max_timeout > -1) {
664 maxtv.tv_sec = max_timeout / 1000;
665 maxtv.tv_usec = max_timeout % (max_timeout * 1000);
666 }
667
668 return ares_timeout(ares->channel, max_timeout > -1 ? &maxtv : NULL, tv_buf);
669 }
670 /* }}} */
671
672 local int php_ares_process(php_ares *ares, long max_timeout) /* {{{ */
673 {
674 int nfds;
675 fd_set R, W;
676 struct timeval tv;
677
678 FD_ZERO(&R);
679 FD_ZERO(&W);
680
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);
684 }
685 }
686
687 return nfds;
688 }
689 /* }}} */
690
691 local int php_ares_publish_fds(fd_set *R, fd_set *W, zval *r, zval *w) /* {{{ */
692 {
693 int i, nfds = 0;
694
695 for (i = 0; i < FD_SETSIZE; ++i) {
696 if (FD_ISSET(i, R)) {
697 add_next_index_long(r, i);
698 if (i > nfds) {
699 nfds = i;
700 }
701 }
702 }
703
704 for (i = 0; i < FD_SETSIZE; ++i) {
705 if (FD_ISSET(i, W)) {
706 add_next_index_long(w, i);
707 if (i > nfds) {
708 nfds = i;
709 }
710 }
711 }
712
713 return nfds ? nfds + 1 : 0;
714 }
715 /* }}} */
716
717 local int php_ares_extract_fds(zval *r, zval *w, fd_set *R, fd_set *W) /* {{{ */
718 {
719 zval **fd;
720 int nfds = 0;
721
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);
730 }
731 }
732 }
733 }
734
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);
743 }
744 }
745 }
746 }
747
748 return nfds ? nfds + 1 : 0;
749 }
750 /* }}} */
751
752 static void php_ares_query_llist_dtor(void *entry)
753 {
754 php_ares_query *q = *(php_ares_query **) entry;
755 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
756 zend_list_delete(q->id);
757 }
758
759 #ifdef HAVE_ARES_VERSION
760 /* {{{ proto string ares_version()
761 Get libares version */
762 static PHP_FUNCTION(ares_version)
763 {
764 if (ZEND_NUM_ARGS()) {
765 WRONG_PARAM_COUNT;
766 }
767
768 RETURN_STRING(estrdup(ares_version(NULL)), 0);
769 }
770 /* }}} */
771 #endif
772
773 /* {{{ proto resource ares_init([array options])
774 Create an ares resource */
775 static PHP_FUNCTION(ares_init)
776 {
777 zval *opt_array = NULL;
778 php_ares *ares = NULL;
779 int err;
780
781 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &opt_array)) {
782 RETURN_FALSE;
783 }
784
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);
789
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);
793 efree(ares);
794 RETURN_ARES_ERROR(err);
795 }
796
797 ZEND_REGISTER_RESOURCE(return_value, ares, le_ares);
798 }
799 /* }}} */
800
801 /* {{{ proto void ares_destroy(resource ares)
802 Destroy the ares handle */
803 static PHP_FUNCTION(ares_destroy)
804 {
805 zval *rsrc;
806 php_ares *ares;
807
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");
812 } else {
813 zend_list_delete(Z_LVAL_P(rsrc));
814 }
815 }
816 }
817 /* }}} */
818
819 /* {{{ proto string ares_strerror(int status)
820 Get description of status code */
821 static PHP_FUNCTION(ares_strerror)
822 {
823 long err;
824 #ifdef HAVE_OLD_ARES_STRERROR
825 char *__tmp = NULL;
826 const char *__err;
827 #endif
828
829 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &err)) {
830 RETURN_FALSE;
831 }
832
833 #ifdef HAVE_OLD_ARES_STRERROR
834 __err = ares_strerror(err, &__tmp);
835 RETVAL_STRING(estrdup(__err), 0);
836 if (__tmp) {
837 ares_free_errmem(__tmp);
838 }
839 #else
840 RETURN_STRING(estrdup(ares_strerror(err)), 0);
841 #endif
842 }
843 /* }}} */
844
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)
848 {
849 char *name_str, *query_str;
850 int name_len, query_len, err;
851 long dnsclass, type, id, rd;
852
853 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &name_str, &name_len, &dnsclass, &type, &id, &rd)) {
854 RETURN_FALSE;
855 }
856
857 if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, (unsigned char **) &query_str, &query_len))) {
858 RETURN_ARES_ERROR(err);
859 }
860 RETVAL_STRINGL(query_str, query_len, 1);
861 ares_free_string(query_str);
862 }
863 /* }}} */
864
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)
868 {
869 zval *rsrc, *cb = NULL;
870 php_ares *ares;
871 php_ares_query *query;
872 char *name;
873 int name_len;
874 long dnsclass = ns_c_in, type = ns_t_a;
875
876 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
877 RETURN_FALSE;
878 }
879 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
880
881 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
882 RETURN_ARES_CB_ERROR("second");
883 }
884
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);
889 }
890 /* }}} */
891
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)
895 {
896 zval *rsrc, *cb = NULL;
897 php_ares *ares;
898 php_ares_query *query;
899 char *name;
900 int name_len;
901 long dnsclass = ns_c_in, type = ns_t_a;
902
903 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
904 RETURN_FALSE;
905 }
906 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
907
908 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
909 RETURN_ARES_CB_ERROR("second");
910 }
911
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);
916 }
917 /* }}} */
918
919 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
920 Send custom query */
921 static PHP_FUNCTION(ares_send)
922 {
923 zval *rsrc, *cb = NULL;
924 php_ares *ares;
925 php_ares_query *query;
926 char *buf;
927 int len;
928
929 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s", &rsrc, &cb, &buf, &len)) {
930 RETURN_FALSE;
931 }
932 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
933
934 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
935 RETURN_ARES_CB_ERROR("second");
936 }
937
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);
942 }
943 /* }}} */
944
945 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
946 Get host by name */
947 static PHP_FUNCTION(ares_gethostbyname)
948 {
949 zval *rsrc, *cb = NULL;
950 php_ares *ares;
951 php_ares_query *query;
952 char *name;
953 int name_len;
954 long family = AF_INET;
955
956 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &name, &name_len, &family)) {
957 RETURN_FALSE;
958 }
959 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
960
961 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
962 RETURN_ARES_CB_ERROR("second");
963 }
964
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);
969 }
970 /* }}} */
971
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)
975 {
976 zval *rsrc, *cb = NULL;
977 php_ares *ares;
978 php_ares_query *query;
979 char *addr;
980 int addr_len;
981 long family = AF_INET;
982 void *sa;
983 int sa_len;
984
985 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &addr, &addr_len, &family)) {
986 RETURN_FALSE;
987 }
988 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
989
990 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
991 PHP_ARES_CB_ERROR("second");
992 RETURN_FALSE;
993 }
994
995 switch (family) {
996 case AF_INET:
997 sa = emalloc(sa_len = sizeof(struct in_addr));
998 break;
999 case AF_INET6:
1000 sa = emalloc(sa_len = sizeof(struct in6_addr));
1001 break;
1002 default:
1003 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
1004 RETURN_FALSE;
1005 break;
1006 }
1007
1008 if (1 > inet_pton(family, addr, sa)) {
1009 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1010 RETVAL_FALSE;
1011 } else {
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);
1016 }
1017 efree(sa);
1018 }
1019 /* }}} */
1020
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]])
1023 Get name info */
1024 static PHP_FUNCTION(ares_getnameinfo)
1025 {
1026 zval *rsrc, *cb = NULL;
1027 php_ares *ares;
1028 php_ares_query *query;
1029 char *addr;
1030 int addr_len;
1031 long flags, port = 0, family = AF_INET;
1032 struct sockaddr *sa;
1033 struct sockaddr_in *in;
1034 struct sockaddr_in6 *in6;
1035 int sa_len;
1036
1037 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!ls|ll", &rsrc, &cb, &flags, &addr, &addr_len, &family, &port)) {
1038 RETURN_FALSE;
1039 }
1040 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1041
1042 if (cb && !IS_CALLABLE(cb, 0, NULL)) {
1043 PHP_ARES_CB_ERROR("second");
1044 RETURN_FALSE;
1045 }
1046
1047 RETVAL_TRUE;
1048 switch (family) {
1049 case AF_INET:
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);
1055 RETVAL_FALSE;
1056 }
1057 sa = (struct sockaddr *) in;
1058 break;
1059 case AF_INET6:
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);
1065 RETVAL_FALSE;
1066 }
1067 sa = (struct sockaddr *) in6;
1068 break;
1069 default:
1070 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither AF_INET nor AF_INET6");
1071 RETURN_FALSE;
1072 break;
1073 }
1074
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);
1080 }
1081 efree(sa);
1082 }
1083 /* }}} */
1084 #endif
1085
1086 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1087 Check a query for its result */
1088 static PHP_FUNCTION(ares_result)
1089 {
1090 zval *rsrc, *zerrno = NULL, *zerror = NULL;
1091 php_ares_query *query;
1092
1093 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|zz", &rsrc, &zerrno, &zerror)) {
1094 RETURN_FALSE;
1095 }
1096 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1097
1098 if (zerrno) {
1099 zval_dtor(zerrno);
1100 ZVAL_LONG(zerrno, query->error);
1101 }
1102 if (zerror) {
1103 zval_dtor(zerror);
1104 ZVAL_NULL(zerror);
1105 }
1106
1107 switch (query->error) {
1108 case 0:
1109 switch (query->type) {
1110 case PHP_ARES_CB_STD:
1111 RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
1112 break;
1113 case PHP_ARES_CB_HOST:
1114 object_init(return_value);
1115 php_ares_hostent_to_struct(&query->result.host, HASH_OF(return_value));
1116 break;
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);
1121 break;
1122 }
1123 break;
1124 case -1:
1125 RETVAL_FALSE;
1126 break;
1127 default:
1128 if (zerror) {
1129 #ifdef HAVE_OLD_ARES_STRERROR
1130 char *__tmp = NULL;
1131 const char *__err = ares_strerror(query->error, &__tmp);
1132 ZVAL_STRING(zerror, estrdup(__err), 0);
1133 if (__tmp) ares_free_errmem(__tmp);
1134 #else
1135 ZVAL_STRING(zerror, estrdup(ares_strerror(query->error)), 0);
1136 #endif
1137 }
1138 RETVAL_FALSE;
1139 break;
1140 }
1141 }
1142 /* }}} */
1143
1144 /* {{{ proto object ares_packet(resource query)
1145 Check a query for its question packet */
1146 static PHP_FUNCTION(ares_packet)
1147 {
1148 zval *rsrc, *prop;
1149 php_ares_query *query;
1150
1151 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1152 RETURN_FALSE;
1153 }
1154 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1155
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);
1165
1166 switch (query->packet.type) {
1167 case PHP_ARES_PCKT_SEARCH:
1168 object_init(prop);
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);
1173 break;
1174
1175 case PHP_ARES_PCKT_QUERY:
1176 object_init(prop);
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);
1181 break;
1182
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);
1186 break;
1187
1188 case PHP_ARES_PCKT_HNAME:
1189 object_init(prop);
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);
1193 break;
1194
1195 case PHP_ARES_PCKT_HADDR:
1196 object_init(prop);
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);
1200 break;
1201
1202 case PHP_ARES_PCKT_NINFO:
1203 object_init(prop);
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);
1209 break;
1210 }
1211
1212 zval_ptr_dtor(&prop);
1213 }
1214 /* }}} */
1215
1216 #ifdef HAVE_ARES_CANCEL
1217 /* {{{ proto void ares_cancel(resource ares)
1218 Cancel pending queries */
1219 static PHP_FUNCTION(ares_cancel)
1220 {
1221 zval *rsrc;
1222 php_ares *ares;
1223
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);
1227 }
1228 }
1229 /* }}} */
1230 #endif
1231
1232 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1233 Process all pending queries */
1234 static PHP_FUNCTION(ares_process_all)
1235 {
1236 zval *rsrc;
1237 php_ares *ares;
1238 long max_timeout = -1;
1239
1240 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1241 RETURN_FALSE;
1242 }
1243 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1244
1245 while (php_ares_process(ares, max_timeout));
1246 }
1247 /* }}} */
1248
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)
1252 {
1253 zval *rsrc;
1254 php_ares *ares;
1255 long max_timeout = -1;
1256
1257 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1258 RETURN_FALSE;
1259 }
1260 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1261
1262 RETVAL_BOOL(php_ares_process(ares, max_timeout));
1263 }
1264 /* }}} */
1265
1266 /* {{{ proto void ares_process(resource ares, array read, array write)
1267 Process call */
1268 static PHP_FUNCTION(ares_process)
1269 {
1270 zval *rsrc, *read = NULL, *write = NULL;
1271 fd_set R, W;
1272 php_ares *ares;
1273
1274 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a!a!", &rsrc, &read, &write)) {
1275 RETURN_FALSE;
1276 }
1277 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1278
1279 FD_ZERO(&R);
1280 FD_ZERO(&W);
1281
1282 php_ares_extract_fds(read, write, &R, &W);
1283 ares_process(ares->channel, &R, &W);
1284 }
1285 /* }}} */
1286
1287 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1288 Select call */
1289 static PHP_FUNCTION(ares_select)
1290 {
1291 zval *read = NULL, *write = NULL;
1292 fd_set R, W;
1293 int nfds;
1294 long timeout;
1295 struct timeval tv;
1296
1297 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aal", &read, &write, &timeout)) {
1298 RETURN_FALSE;
1299 }
1300
1301 if (timeout) {
1302 tv.tv_sec = timeout / 1000;
1303 tv.tv_usec = timeout % (timeout * 1000);
1304 } else {
1305 tv.tv_sec = 1;
1306 tv.tv_usec = 0;
1307 }
1308
1309 FD_ZERO(&R);
1310 FD_ZERO(&W);
1311
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);
1317 RETURN_TRUE;
1318 }
1319 RETURN_FALSE;
1320 }
1321 /* }}} */
1322
1323 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1324 Get suggested select timeout in ms */
1325 static PHP_FUNCTION(ares_timeout)
1326 {
1327 zval *rsrc;
1328 long max_timeout = -1;
1329 struct timeval tv, *tvptr;
1330 php_ares *ares;
1331
1332 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1333 RETURN_FALSE;
1334 }
1335 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1336
1337 if ((tvptr = php_ares_timeout(ares, max_timeout, &tv))) {
1338 RETURN_LONG(tvptr->tv_sec * 1000 + tvptr->tv_usec / 1000);
1339 }
1340 RETURN_LONG(0);
1341 }
1342 /* }}} */
1343
1344 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1345 Get file descriptors */
1346 static PHP_FUNCTION(ares_fds)
1347 {
1348 zval *rsrc, *read, *write;
1349 fd_set R, W;
1350 php_ares *ares;
1351
1352 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzz", &rsrc, &read, &write)) {
1353 RETURN_FALSE;
1354 }
1355 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1356
1357 FD_ZERO(&R);
1358 FD_ZERO(&W);
1359
1360 zval_dtor(read);
1361 zval_dtor(write);
1362 array_init(read);
1363 array_init(write);
1364 ares_fds(ares->channel, &R, &W);
1365 RETVAL_LONG(php_ares_publish_fds(&R, &W, read, write));
1366 }
1367 /* }}} */
1368
1369 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor)
1370 {
1371 php_ares *ares = (php_ares *) rsrc->ptr;
1372
1373 ares_destroy(ares->channel);
1374 zend_llist_destroy(&ares->queries);
1375 php_ares_options_dtor(&ares->options);
1376 efree(ares);
1377 }
1378
1379 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor)
1380 {
1381 php_ares_query *query = (php_ares_query *) rsrc->ptr;
1382
1383 php_ares_query_dtor(query);
1384 efree(query);
1385 }
1386
1387 /* {{{ PHP_MINIT_FUNCTION */
1388 static PHP_MINIT_FUNCTION(ares)
1389 {
1390 #ifdef HAVE_ARES_VERSION
1391 int ares_version_num;
1392 ares_version(&ares_version_num);
1393
1394 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
1395 #endif
1396
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);
1414 #ifdef ARES_EBADSTR
1415 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR, CONST_PERSISTENT|CONST_CS);
1416 #endif
1417 #ifdef ARES_EBADFLAGS
1418 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS, CONST_PERSISTENT|CONST_CS);
1419 #endif
1420 #ifdef ARES_ENONAME
1421 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME, CONST_PERSISTENT|CONST_CS);
1422 #endif
1423 #ifdef ARES_EBADHINTS
1424 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS, CONST_PERSISTENT|CONST_CS);
1425 #endif
1426
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);
1435
1436 /*
1437 * Address Family Constants
1438 */
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);
1441
1442 /*
1443 * Name Info constants
1444 */
1445 #ifdef ARES_NI_NOFQDN
1446 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN, CONST_PERSISTENT|CONST_CS);
1447 #endif
1448 #ifdef ARES_NI_NUMERICHOST
1449 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1450 #endif
1451 #ifdef ARES_NI_NAMEREQD
1452 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD, CONST_PERSISTENT|CONST_CS);
1453 #endif
1454 #ifdef ARES_NI_NUMERICSERV
1455 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1456 #endif
1457 #ifdef ARES_NI_DGRAM
1458 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM, CONST_PERSISTENT|CONST_CS);
1459 #endif
1460 #ifdef ARES_NI_TCP
1461 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP, CONST_PERSISTENT|CONST_CS);
1462 #endif
1463 #ifdef ARES_NI_UDP
1464 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP, CONST_PERSISTENT|CONST_CS);
1465 #endif
1466 #ifdef ARES_NI_SCTP
1467 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP, CONST_PERSISTENT|CONST_CS);
1468 #endif
1469 #ifdef ARES_NI_DCCP
1470 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP, CONST_PERSISTENT|CONST_CS);
1471 #endif
1472 #ifdef ARES_NI_NUMERICSCOPE
1473 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE, CONST_PERSISTENT|CONST_CS);
1474 #endif
1475 #ifdef ARES_NI_LOOKUPHOST
1476 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST, CONST_PERSISTENT|CONST_CS);
1477 #endif
1478 #ifdef ARES_NI_LOOKUPSERVICE
1479 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE, CONST_PERSISTENT|CONST_CS);
1480 #endif
1481 #ifdef ARES_NI_IDN
1482 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN, CONST_PERSISTENT|CONST_CS);
1483 #endif
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);
1486 #endif
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);
1489 #endif
1490
1491 /*
1492 * Address Info constants
1493 */
1494 #ifdef ARES_AI_CANONNAME
1495 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME, CONST_PERSISTENT|CONST_CS);
1496 #endif
1497 #ifdef ARES_AI_NUMERICHOST
1498 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1499 #endif
1500 #ifdef ARES_AI_PASSIVE
1501 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE, CONST_PERSISTENT|CONST_CS);
1502 #endif
1503 #ifdef ARES_AI_NUMERICSERV
1504 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1505 #endif
1506 #ifdef ARES_AI_V
1507 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V, CONST_PERSISTENT|CONST_CS);
1508 #endif
1509 #ifdef ARES_AI_ALL
1510 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL, CONST_PERSISTENT|CONST_CS);
1511 #endif
1512 #ifdef ARES_AI_ADDRCONFIG
1513 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG, CONST_PERSISTENT|CONST_CS);
1514 #endif
1515 #ifdef ARES_AI_IDN
1516 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN, CONST_PERSISTENT|CONST_CS);
1517 #endif
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);
1520 #endif
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);
1523 #endif
1524 #ifdef ARES_AI_CANONIDN
1525 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN, CONST_PERSISTENT|CONST_CS);
1526 #endif
1527 #ifdef ARES_AI_MASK
1528 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK, CONST_PERSISTENT|CONST_CS);
1529 #endif
1530 #ifdef ARES_GETSOCK_MAXNUM
1531 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM, CONST_PERSISTENT|CONST_CS);
1532 #endif
1533
1534 /*
1535 * ns_t (type) constants (arpa/nameser.h)
1536 */
1537
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);
1578 /* (21) Router. */
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);
1632
1633 /*
1634 * ns_c (dnsclass) constants (arpa/nameser.h)
1635 */
1636
1637 /* (1) Internet. */
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);
1649
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);
1652
1653 return SUCCESS;
1654 }
1655 /* }}} */
1656
1657 /* {{{ PHP_MINFO_FUNCTION */
1658 static PHP_MINFO_FUNCTION(ares)
1659 {
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();
1664
1665 php_info_print_table_start();
1666 php_info_print_table_header(3, "Used Library", "compiled", "linked");
1667 php_info_print_table_row(3,
1668 PHP_ARES_LIBNAME,
1669 #ifdef ARES_VERSION_STR
1670 ARES_VERSION_STR,
1671 #else
1672 "unkown",
1673 #endif
1674 #ifdef HAVE_ARES_VERSION
1675 ares_version(NULL)
1676 #else
1677 "unkown"
1678 #endif
1679 );
1680 php_info_print_table_end();
1681 }
1682 /* }}} */
1683
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();
1690
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();
1696
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();
1702 #else
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};
1706 #endif
1707
1708 /* {{{ ares_functions[] */
1709 zend_function_entry ares_functions[] = {
1710 #ifdef HAVE_ARES_VERSION
1711 PHP_FE(ares_version, NULL)
1712 #endif
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)
1718 #endif
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)
1727 #endif
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)
1736 {NULL, NULL, NULL}
1737 };
1738 /* }}} */
1739
1740 /* {{{ ares_module_entry */
1741 zend_module_entry ares_module_entry = {
1742 STANDARD_MODULE_HEADER,
1743 "ares",
1744 ares_functions,
1745 PHP_MINIT(ares),
1746 NULL,
1747 NULL,
1748 NULL,
1749 PHP_MINFO(ares),
1750 PHP_ARES_VERSION,
1751 STANDARD_MODULE_PROPERTIES
1752 };
1753 /* }}} */
1754
1755 #ifdef COMPILE_DL_ARES
1756 ZEND_GET_MODULE(ares)
1757 #endif
1758
1759 /*
1760 * Local variables:
1761 * tab-width: 4
1762 * c-basic-offset: 4
1763 * End:
1764 * vim600: noet sw=4 ts=4 fdm=marker
1765 * vim<600: noet sw=4 ts=4
1766 */