dropped unused functions;
[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 zend_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
53 #define PHP_ARES_LE_NAME "AsyncResolver"
54 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
55 static int le_ares;
56 static int le_ares_query;
57
58 #ifdef HAVE_OLD_ARES_STRERROR
59 # define PHP_ARES_ERROR(err) { \
60 char *__tmp = NULL; \
61 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err, &__tmp)); \
62 if (__tmp) ares_free_errmem(__tmp); \
63 }
64 #else
65 # define PHP_ARES_ERROR(err) \
66 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ares_strerror(err))
67 #endif
68
69 #define RETURN_ARES_ERROR(err) \
70 PHP_ARES_ERROR(err); \
71 RETURN_FALSE
72 #define PHP_ARES_CB_ERROR(param) \
73 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected the " param " argument to be a valid callback")
74 #define RETURN_ARES_CB_ERROR(param) \
75 PHP_ARES_CB_ERROR(param); \
76 RETURN_FALSE
77
78 /* {{{ typedefs */
79 typedef struct _php_ares_options {
80 struct ares_options strct;
81 int flags;
82 } php_ares_options;
83
84 typedef struct _php_ares {
85 ares_channel channel;
86 php_ares_options options;
87 zend_llist queries;
88 void ***tsrm_ls;
89 unsigned in_callback:1;
90 unsigned reserved:31;
91 } php_ares;
92
93 typedef enum _php_ares_query_type {
94 PHP_ARES_CB_STD,
95 PHP_ARES_CB_HOST,
96 PHP_ARES_CB_NINFO,
97 } php_ares_query_type;
98
99 typedef enum _php_ares_query_packet_type {
100 PHP_ARES_PCKT_SEARCH,
101 PHP_ARES_PCKT_QUERY,
102 PHP_ARES_PCKT_SEND,
103 PHP_ARES_PCKT_HNAME,
104 PHP_ARES_PCKT_HADDR,
105 PHP_ARES_PCKT_NINFO,
106 } php_ares_query_packet_type;
107
108 typedef union _php_ares_query_packet_data {
109 struct {
110 char *name;
111 int name_len;
112 long type;
113 long dnsclass;
114 } search;
115 struct {
116 char *name;
117 int name_len;
118 long type;
119 long dnsclass;
120 } query;
121 struct {
122 char *buf;
123 int len;
124 } send;
125 struct {
126 char *name;
127 int name_len;
128 long family;
129 } hname;
130 struct {
131 char *addr;
132 int addr_len;
133 long family;
134 } haddr;
135 struct {
136 char *addr;
137 int addr_len;
138 long port;
139 long family;
140 long flags;
141 } ninfo;
142 } php_ares_query_packet_data;
143
144 typedef struct _php_ares_query_packet {
145 php_ares_query_packet_type type;
146 php_ares_query_packet_data data;
147 } php_ares_query_packet;
148
149 typedef union _php_ares_query_result {
150 struct {
151 char *buf;
152 int len;
153 } std;
154 struct hostent host;
155 struct {
156 char *service;
157 char *node;
158 } ninfo;
159 } php_ares_query_result;
160
161 typedef struct _php_ares_query {
162 int id;
163 int error;
164 php_ares *ares;
165 zval *callback;
166 php_ares_query_type type;
167 php_ares_query_packet packet;
168 php_ares_query_result result;
169 } php_ares_query;
170 /* }}} */
171
172 local struct hostent *php_ares_hostent_ctor(struct hostent *host) /* {{{ */
173 {
174 if (!host) {
175 host = emalloc(sizeof(struct hostent));
176 }
177 memset(host, 0, sizeof(struct hostent));
178
179 return host;
180 }
181 /* }}} */
182
183 local void php_ares_hostent_copy(struct hostent *from, struct hostent *to) /* {{{ */
184 {
185 int i, c;
186 char **ptr;
187
188 memcpy(to, from, sizeof(struct hostent));
189 to->h_name = estrdup(from->h_name);
190 for (c = 0, ptr = from->h_aliases; *ptr; ++ptr, ++c);
191 to->h_aliases = ecalloc((c+1), sizeof(char *));
192 for (i = 0; i < c; ++i) {
193 to->h_aliases[i] = estrdup(from->h_aliases[i]);
194 }
195 for (c = 0, ptr = from->h_addr_list; *ptr; ++ptr, ++c);
196 to->h_addr_list = ecalloc((c+1), sizeof(char *));
197 for (i = 0; i < c; ++i) {
198 to->h_addr_list[i] = emalloc(from->h_length);
199 memcpy(to->h_addr_list[i], from->h_addr_list[i], from->h_length);
200 }
201 }
202 /* }}} */
203
204 local void php_ares_hostent_to_struct(struct hostent *hostent, HashTable *ht) /* {{{ */
205 {
206 zval array, *tmp;
207 char **ptr;
208
209 INIT_PZVAL(&array);
210 Z_TYPE(array) = IS_ARRAY;
211 Z_ARRVAL(array) = ht;
212
213 if (hostent) {
214 add_assoc_string(&array, "name", hostent->h_name, 1);
215
216 MAKE_STD_ZVAL(tmp);
217 array_init(tmp);
218 if (hostent->h_aliases) {
219 for (ptr = hostent->h_aliases; *ptr; ++ptr) {
220 add_next_index_string(tmp, *ptr, 1);
221 }
222 }
223 add_assoc_zval(&array, "aliases", tmp);
224 add_assoc_long(&array, "addrtype", hostent->h_addrtype);
225
226 MAKE_STD_ZVAL(tmp);
227 array_init(tmp);
228 if (hostent->h_addr_list) {
229 for (ptr = hostent->h_addr_list; *ptr; ++ptr) {
230 char name[64] = {0};
231
232 if (inet_ntop(hostent->h_addrtype, *ptr, name, sizeof(name)-1)) {
233 add_next_index_string(tmp, name, 1);
234 }
235 }
236 }
237 add_assoc_zval(&array, "addrlist", tmp);
238 }
239 }
240 /* }}} */
241
242 local void php_ares_hostent_dtor(struct hostent *host) /* {{{ */
243 {
244 char **ptr;
245
246 STR_FREE(host->h_name);
247 if (host->h_aliases) {
248 for (ptr = host->h_aliases; *ptr; ++ptr) {
249 efree(*ptr);
250 }
251 efree(host->h_aliases);
252 }
253 if (host->h_addr_list) {
254 for (ptr = host->h_addr_list; *ptr; ++ptr) {
255 efree(*ptr);
256 }
257 efree(host->h_addr_list);
258 }
259 memset(host, 0, sizeof(struct hostent));
260 }
261 /* }}} */
262
263 local void php_ares_hostent_free(struct hostent **host) /* {{{ */
264 {
265 php_ares_hostent_dtor(*host);
266 efree(*host);
267 *host = NULL;
268 }
269 /* }}} */
270
271 local php_ares_query *php_ares_query_ctor(php_ares_query *query, php_ares_query_type type, php_ares *ares, zval *callback) /* {{{ */
272 {
273 if (!query) {
274 query = emalloc(sizeof(php_ares_query));
275 }
276 memset(query, 0, sizeof(php_ares_query));
277
278 query->ares = ares;
279 query->type = type;
280 query->error = -1;
281
282 if (callback) {
283 ZVAL_ADDREF(callback);
284 query->callback = callback;
285 }
286
287 return query;
288 }
289 /* }}} */
290
291 local void php_ares_query_rsrc(php_ares_query *query, zval *return_value) /* {{{ */
292 {
293 TSRMLS_FETCH_FROM_CTX(query->ares->tsrm_ls);
294
295 ZEND_REGISTER_RESOURCE(return_value, query, le_ares_query);
296 query->id = Z_LVAL_P(return_value);
297 zend_list_addref(query->id);
298 zend_llist_add_element(&query->ares->queries, &query);
299 }
300 /* }}} */
301
302 local void php_ares_query_pckt(php_ares_query *query, php_ares_query_packet_type type, ...)
303 {
304 va_list argv;
305 char *buf;
306 int len;
307
308 va_start(argv, type);
309
310 switch (query->packet.type = type) {
311 case PHP_ARES_PCKT_SEARCH:
312 buf = va_arg(argv, char *);
313 len = va_arg(argv, int);
314 query->packet.data.search.name = estrndup(buf, len);
315 query->packet.data.search.name_len = len;
316 query->packet.data.search.type = va_arg(argv, long);
317 query->packet.data.search.dnsclass = va_arg(argv, long);
318 break;
319
320 case PHP_ARES_PCKT_QUERY:
321 buf = va_arg(argv, char *);
322 len = va_arg(argv, int);
323 query->packet.data.query.name = estrndup(buf, len);
324 query->packet.data.query.name_len = len;
325 query->packet.data.query.type = va_arg(argv, long);
326 query->packet.data.query.dnsclass = va_arg(argv, long);
327 break;
328
329 case PHP_ARES_PCKT_SEND:
330 buf = va_arg(argv, char *);
331 len = va_arg(argv, int);
332 query->packet.data.send.buf = estrndup(buf, len);
333 query->packet.data.send.len = len;
334 break;
335
336 case PHP_ARES_PCKT_HNAME:
337 buf = va_arg(argv, char *);
338 len = va_arg(argv, int);
339 query->packet.data.hname.name = estrndup(buf, len);
340 query->packet.data.hname.name_len = len;
341 query->packet.data.hname.family = va_arg(argv, long);
342 break;
343
344 case PHP_ARES_PCKT_HADDR:
345 buf = va_arg(argv, char *);
346 len = va_arg(argv, int);
347 query->packet.data.haddr.addr = estrndup(buf, len);
348 query->packet.data.haddr.addr_len = len;
349 query->packet.data.haddr.family = va_arg(argv, long);
350 break;
351
352 case PHP_ARES_PCKT_NINFO:
353 query->packet.data.ninfo.flags = va_arg(argv, long);
354 buf = va_arg(argv, char *);
355 len = va_arg(argv, int);
356 query->packet.data.ninfo.addr = estrndup(buf, len);
357 query->packet.data.ninfo.addr_len = len;
358 query->packet.data.ninfo.family = va_arg(argv, long);
359 query->packet.data.ninfo.port = va_arg(argv, long);
360 break;
361 }
362
363 va_end(argv);
364 }
365
366 local void php_ares_query_dtor(php_ares_query *query) /* {{{ */
367 {
368 struct php_ares_query_packet_buf {char *buf;} *packet;
369
370 packet = (struct php_ares_query_packet_buf *) &query->packet.data;
371 if (packet->buf) {
372 efree(packet->buf);
373 }
374 switch (query->type) {
375 case PHP_ARES_CB_STD:
376 STR_FREE(query->result.std.buf);
377 break;
378 case PHP_ARES_CB_HOST:
379 php_ares_hostent_dtor(&query->result.host);
380 break;
381 case PHP_ARES_CB_NINFO:
382 STR_FREE(query->result.ninfo.service);
383 STR_FREE(query->result.ninfo.node);
384 break;
385 }
386 if (query->callback) {
387 zval_ptr_dtor(&query->callback);
388 }
389 memset(query, 0, sizeof(php_ares_query));
390 }
391 /* }}} */
392
393 local void php_ares_query_free(php_ares_query **query) /* {{{ */
394 {
395 php_ares_query_dtor(*query);
396 efree(*query);
397 *query = NULL;
398 }
399 /* }}} */
400
401 local php_ares_options *php_ares_options_ctor(php_ares_options *options, HashTable *ht) /* {{{ */
402 {
403 int i;
404 zval **opt, **entry;
405
406 if (!options) {
407 options = emalloc(sizeof(php_ares_options));
408 }
409 memset(options, 0, sizeof(php_ares_options));
410
411 if (ht && zend_hash_num_elements(ht)) {
412 if ((SUCCESS == zend_hash_find(ht, "flags", sizeof("flags"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
413 options->flags |= ARES_OPT_FLAGS;
414 options->strct.flags = Z_LVAL_PP(opt);
415 }
416 if ((SUCCESS == zend_hash_find(ht, "timeout", sizeof("timeout"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
417 options->flags |= ARES_OPT_TIMEOUT;
418 options->strct.timeout = Z_LVAL_PP(opt);
419 }
420 if ((SUCCESS == zend_hash_find(ht, "tries", sizeof("tries"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
421 options->flags |= ARES_OPT_TRIES;
422 options->strct.tries = Z_LVAL_PP(opt);
423 }
424 if ((SUCCESS == zend_hash_find(ht, "ndots", sizeof("ndots"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
425 options->flags |= ARES_OPT_NDOTS;
426 options->strct.ndots = Z_LVAL_PP(opt);
427 }
428 if ((SUCCESS == zend_hash_find(ht, "udp_port", sizeof("udp_port"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
429 options->flags |= ARES_OPT_UDP_PORT;
430 options->strct.udp_port = htons((unsigned short) Z_LVAL_PP(opt));
431 }
432 if ((SUCCESS == zend_hash_find(ht, "tcp_port", sizeof("tcp_port"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
433 options->flags |= ARES_OPT_TCP_PORT;
434 options->strct.tcp_port = htons((unsigned short) Z_LVAL_PP(opt));
435 }
436 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)))) {
437 options->strct.servers = ecalloc(i, sizeof(struct in_addr));
438 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
439 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
440 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
441 if (Z_TYPE_PP(entry) == IS_STRING) {
442 inet_aton(Z_STRVAL_PP(entry), &options->strct.servers[options->strct.nservers++]);
443 }
444 }
445 if (options->strct.nservers) {
446 options->flags |= ARES_OPT_SERVERS;
447 }
448 }
449 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)))) {
450 options->strct.domains = ecalloc(i, sizeof(char *));
451 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_PP(opt));
452 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_PP(opt), (void *) &entry);
453 zend_hash_move_forward(Z_ARRVAL_PP(opt))) {
454 if (Z_TYPE_PP(entry) == IS_STRING) {
455 options->strct.domains[options->strct.ndomains++] = estrdup(Z_STRVAL_PP(entry));
456 }
457 }
458 if (options->strct.ndomains) {
459 options->flags |= ARES_OPT_DOMAINS;
460 }
461 }
462 if ((SUCCESS == zend_hash_find(ht, "lookups", sizeof("lookups"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_STRING)) {
463 options->flags |= ARES_OPT_LOOKUPS;
464 options->strct.lookups = estrdup(Z_STRVAL_PP(opt));
465 }
466 }
467
468 return options;
469 }
470 /* }}} */
471
472 local void php_ares_options_dtor(php_ares_options *options) /* {{{ */
473 {
474 int i;
475
476 if (options->strct.servers) {
477 efree(options->strct.servers);
478 }
479
480 if (options->strct.domains) {
481 for (i = 0; i < options->strct.ndomains; ++i) {
482 efree(options->strct.domains[i]);
483 }
484 efree(options->strct.domains);
485 }
486
487 STR_FREE(options->strct.lookups);
488
489 memset(options, 0, sizeof(php_ares_options));
490 }
491 /* }}} */
492
493 local void php_ares_options_free(php_ares_options **options) /* {{{ */
494 {
495 php_ares_options_dtor(*options);
496 efree(*options);
497 *options = NULL;
498 }
499 /* }}} */
500
501 /* {{{ callbacks */
502 static void php_ares_callback_func(void *aq, int status, unsigned char *abuf, int alen)
503 {
504 php_ares_query *q = (php_ares_query *) aq;
505 zval *params[3], *retval;
506 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
507
508 q->error = status;
509 if (abuf) {
510 q->result.std.buf = estrndup((char *) abuf, alen);
511 q->result.std.len = alen;
512 }
513
514 if (q->callback) {
515 MAKE_STD_ZVAL(retval);
516 MAKE_STD_ZVAL(params[0]);
517 MAKE_STD_ZVAL(params[1]);
518 MAKE_STD_ZVAL(params[2]);
519 ZVAL_NULL(retval);
520 zend_list_addref(q->id);
521 Z_LVAL_P(params[0]) = q->id;
522 Z_TYPE_P(params[0]) = IS_RESOURCE;
523 ZVAL_LONG(params[1], status);
524 ZVAL_STRINGL(params[2], (char *) abuf, alen, 1);
525
526 q->ares->in_callback = 1;
527 call_user_function(EG(function_table), NULL, q->callback, retval, 3, params TSRMLS_CC);
528 q->ares->in_callback = 0;
529
530 zval_ptr_dtor(&retval);
531 zval_ptr_dtor(&params[0]);
532 zval_ptr_dtor(&params[1]);
533 zval_ptr_dtor(&params[2]);
534 }
535 }
536
537 static void php_ares_host_callback_func(void *aq, int status, struct hostent *hostent)
538 {
539 php_ares_query *q = (php_ares_query *) aq;
540 zval *params[3], *retval;
541 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
542
543 q->error = status;
544 if (hostent) {
545 php_ares_hostent_copy(hostent, &q->result.host);
546 }
547
548 if (q->callback) {
549 MAKE_STD_ZVAL(retval);
550 MAKE_STD_ZVAL(params[0]);
551 MAKE_STD_ZVAL(params[1]);
552 MAKE_STD_ZVAL(params[2]);
553 ZVAL_NULL(retval);
554 zend_list_addref(q->id);
555 Z_LVAL_P(params[0]) = q->id;
556 Z_TYPE_P(params[0]) = IS_RESOURCE;
557 ZVAL_LONG(params[1], status);
558 object_init(params[2]);
559 php_ares_hostent_to_struct(hostent, HASH_OF(params[2]));
560
561 q->ares->in_callback = 1;
562 call_user_function(EG(function_table), NULL, q->callback, retval, 3, params TSRMLS_CC);
563 q->ares->in_callback = 0;
564
565 zval_ptr_dtor(&retval);
566 zval_ptr_dtor(&params[0]);
567 zval_ptr_dtor(&params[1]);
568 zval_ptr_dtor(&params[2]);
569 }
570 }
571
572 #ifdef HAVE_ARES_GETNAMEINFO
573 static void php_ares_nameinfo_callback_func(void *aq, int status, char *node, char *service)
574 {
575 php_ares_query *q = (php_ares_query *) aq;
576 zval *params[4], *retval;
577 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
578
579 q->error = status;
580 if (node) {
581 q->result.ninfo.node = estrdup(node);
582 }
583 if (service) {
584 q->result.ninfo.service = estrdup(service);
585 }
586
587 if (q->callback) {
588 MAKE_STD_ZVAL(retval);
589 MAKE_STD_ZVAL(params[0]);
590 MAKE_STD_ZVAL(params[1]);
591 MAKE_STD_ZVAL(params[2]);
592 MAKE_STD_ZVAL(params[3]);
593 ZVAL_NULL(retval);
594 zend_list_addref(q->id);
595 Z_LVAL_P(params[0]) = q->id;
596 Z_TYPE_P(params[0]) = IS_RESOURCE;
597 ZVAL_LONG(params[1], status);
598 if (node) {
599 ZVAL_STRING(params[2], node, 1);
600 } else {
601 ZVAL_NULL(params[2]);
602 }
603 if (service) {
604 ZVAL_STRING(params[3], service, 1);
605 } else {
606 ZVAL_NULL(params[3]);
607 }
608
609 q->ares->in_callback = 1;
610 call_user_function(EG(function_table), NULL, q->callback, retval, 4, params TSRMLS_CC);
611 q->ares->in_callback = 0;
612
613 zval_ptr_dtor(&retval);
614 zval_ptr_dtor(&params[0]);
615 zval_ptr_dtor(&params[1]);
616 zval_ptr_dtor(&params[2]);
617 zval_ptr_dtor(&params[3]);
618 }
619 }
620 #endif
621
622 #if PHP_ARES_NEW_CALLBACK_API
623 # define php_ares_callback_func php_ares_callback_func_new
624 static void php_ares_callback_func_new(void *aq, int status, int timeouts, unsigned char *abuf, int alen)
625 {
626 php_ares_callback_func_old(aq, status, abuf, alen);
627 }
628
629 # define php_ares_host_callback_func php_ares_host_callback_func_new
630 static void php_ares_host_callback_func_new(void *aq, int status, int timeouts, struct hostent *hostent)
631 {
632 php_ares_host_callback_func_old(aq, status, hostent);
633 }
634
635 # ifdef HAVE_ARES_GETNAMEINFO
636 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
637 static void php_ares_nameinfo_callback_func_new(void *aq, int status, int timeouts, char *node, char *service)
638 {
639 php_ares_nameinfo_callback_func_old(aq, status, node, service);
640 }
641 # endif
642
643 #else
644 # define php_ares_callback_func php_ares_callback_func_new
645 # define php_ares_host_callback_func php_ares_host_callback_func_new
646 # ifdef HAVE_ARES_GETNAMEINFO
647 # define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
648 # endif
649 #endif
650 /* }}} */
651
652 local struct timeval *php_ares_timeout(php_ares *ares, long max_timeout, struct timeval *tv_buf) /* {{{ */
653 {
654 struct timeval maxtv;
655
656 if (max_timeout > -1) {
657 maxtv.tv_sec = max_timeout / 1000;
658 maxtv.tv_usec = max_timeout % (max_timeout * 1000);
659 }
660
661 return ares_timeout(ares->channel, max_timeout > -1 ? &maxtv : NULL, tv_buf);
662 }
663 /* }}} */
664
665 local int php_ares_process(php_ares *ares, long max_timeout) /* {{{ */
666 {
667 int nfds;
668 fd_set R, W;
669 struct timeval tv;
670
671 FD_ZERO(&R);
672 FD_ZERO(&W);
673
674 if ((nfds = ares_fds(ares->channel, &R, &W))) {
675 if (0 < select(nfds, &R, &W, NULL, php_ares_timeout(ares, max_timeout, &tv))) {
676 ares_process(ares->channel, &R, &W);
677 }
678 }
679
680 return nfds;
681 }
682 /* }}} */
683
684 local int php_ares_publish_fds(fd_set *R, fd_set *W, zval *r, zval *w) /* {{{ */
685 {
686 int i, nfds = 0;
687
688 for (i = 0; i < FD_SETSIZE; ++i) {
689 if (FD_ISSET(i, R)) {
690 add_next_index_long(r, i);
691 if (i > nfds) {
692 nfds = i;
693 }
694 }
695 }
696
697 for (i = 0; i < FD_SETSIZE; ++i) {
698 if (FD_ISSET(i, W)) {
699 add_next_index_long(w, i);
700 if (i > nfds) {
701 nfds = i;
702 }
703 }
704 }
705
706 return nfds ? nfds + 1 : 0;
707 }
708 /* }}} */
709
710 local int php_ares_extract_fds(zval *r, zval *w, fd_set *R, fd_set *W) /* {{{ */
711 {
712 zval **fd;
713 int nfds = 0;
714
715 if (r && zend_hash_num_elements(Z_ARRVAL_P(r))) {
716 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(r));
717 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(r), (void *) &fd);
718 zend_hash_move_forward(Z_ARRVAL_P(r))) {
719 if (Z_TYPE_PP(fd) == IS_LONG) {
720 FD_SET(Z_LVAL_PP(fd), R);
721 if (Z_LVAL_PP(fd) > nfds) {
722 nfds = Z_LVAL_PP(fd);
723 }
724 }
725 }
726 }
727
728 if (w && zend_hash_num_elements(Z_ARRVAL_P(w))) {
729 for ( zend_hash_internal_pointer_reset(Z_ARRVAL_P(w));
730 SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(w), (void *) &fd);
731 zend_hash_move_forward(Z_ARRVAL_P(w))) {
732 if (Z_TYPE_PP(fd) == IS_LONG) {
733 FD_SET(Z_LVAL_PP(fd), W);
734 if (Z_LVAL_PP(fd) > nfds) {
735 nfds = Z_LVAL_PP(fd);
736 }
737 }
738 }
739 }
740
741 return nfds ? nfds + 1 : 0;
742 }
743 /* }}} */
744
745 static void php_ares_query_llist_dtor(void *entry)
746 {
747 php_ares_query *q = *(php_ares_query **) entry;
748 TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
749 zend_list_delete(q->id);
750 }
751
752 #ifdef HAVE_ARES_VERSION
753 /* {{{ proto string ares_version()
754 Get libares version */
755 static PHP_FUNCTION(ares_version)
756 {
757 if (ZEND_NUM_ARGS()) {
758 WRONG_PARAM_COUNT;
759 }
760
761 RETURN_STRING(estrdup(ares_version(NULL)), 0);
762 }
763 /* }}} */
764 #endif
765
766 /* {{{ proto resource ares_init([array options])
767 Create an ares resource */
768 static PHP_FUNCTION(ares_init)
769 {
770 zval *opt_array = NULL;
771 php_ares *ares = NULL;
772 int err;
773
774 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &opt_array)) {
775 RETURN_FALSE;
776 }
777
778 ares = emalloc(sizeof(php_ares));
779 TSRMLS_SET_CTX(ares->tsrm_ls);
780 zend_llist_init(&ares->queries, sizeof(php_ares_query *), (llist_dtor_func_t) php_ares_query_llist_dtor, 0);
781 php_ares_options_ctor(&ares->options, opt_array ? Z_ARRVAL_P(opt_array) : NULL);
782
783 if (ARES_SUCCESS != (err = ares_init_options(&ares->channel, &ares->options.strct, ares->options.flags))) {
784 php_ares_options_dtor(&ares->options);
785 zend_llist_destroy(&ares->queries);
786 efree(ares);
787 RETURN_ARES_ERROR(err);
788 }
789
790 ZEND_REGISTER_RESOURCE(return_value, ares, le_ares);
791 }
792 /* }}} */
793
794 /* {{{ proto void ares_destroy(resource ares)
795 Destroy the ares handle */
796 static PHP_FUNCTION(ares_destroy)
797 {
798 zval *rsrc;
799 php_ares *ares;
800
801 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
802 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
803 if (ares->in_callback) {
804 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy ares handle while in callback");
805 } else {
806 zend_list_delete(Z_LVAL_P(rsrc));
807 }
808 }
809 }
810 /* }}} */
811
812 /* {{{ proto string ares_strerror(int status)
813 Get description of status code */
814 static PHP_FUNCTION(ares_strerror)
815 {
816 long err;
817 #ifdef HAVE_OLD_ARES_STRERROR
818 char *__tmp = NULL;
819 const char *__err;
820 #endif
821
822 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &err)) {
823 RETURN_FALSE;
824 }
825
826 #ifdef HAVE_OLD_ARES_STRERROR
827 __err = ares_strerror(err, &__tmp);
828 RETVAL_STRING(estrdup(__err), 0);
829 if (__tmp) {
830 ares_free_errmem(__tmp);
831 }
832 #else
833 RETURN_STRING(estrdup(ares_strerror(err)), 0);
834 #endif
835 }
836 /* }}} */
837
838 /* {{{ proto string ares_mkquery(string name, int dnsclass, int type, int id, int rd)
839 Compose a custom query */
840 static PHP_FUNCTION(ares_mkquery)
841 {
842 char *name_str, *query_str;
843 int name_len, query_len, err;
844 long dnsclass, type, id, rd;
845
846 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &name_str, &name_len, &dnsclass, &type, &id, &rd)) {
847 RETURN_FALSE;
848 }
849
850 if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, (unsigned char **) &query_str, &query_len))) {
851 RETURN_ARES_ERROR(err);
852 }
853 RETVAL_STRINGL(query_str, query_len, 1);
854 ares_free_string(query_str);
855 }
856 /* }}} */
857
858 /* {{{ proto resource ares_search(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
859 Issue a domain search for name */
860 static PHP_FUNCTION(ares_search)
861 {
862 zval *rsrc, *cb = NULL;
863 php_ares *ares;
864 php_ares_query *query;
865 char *name;
866 int name_len;
867 long dnsclass = ns_c_in, type = ns_t_a;
868
869 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
870 RETURN_FALSE;
871 }
872 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
873
874 if (cb && !zend_is_callable(cb, 0, NULL)) {
875 RETURN_ARES_CB_ERROR("second");
876 }
877
878 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
879 php_ares_query_rsrc(query, return_value);
880 php_ares_query_pckt(query, PHP_ARES_PCKT_SEARCH, name, name_len, type, dnsclass);
881 ares_search(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
882 }
883 /* }}} */
884
885 /* {{{ proto resource ares_query(resource ares, mixed callback, string name[, int type = ARES_T_A[, int dnsclass = ARES_C_IN]])
886 Issue a single DNS query */
887 static PHP_FUNCTION(ares_query)
888 {
889 zval *rsrc, *cb = NULL;
890 php_ares *ares;
891 php_ares_query *query;
892 char *name;
893 int name_len;
894 long dnsclass = ns_c_in, type = ns_t_a;
895
896 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
897 RETURN_FALSE;
898 }
899 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
900
901 if (cb && !zend_is_callable(cb, 0, NULL)) {
902 RETURN_ARES_CB_ERROR("second");
903 }
904
905 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
906 php_ares_query_rsrc(query, return_value);
907 php_ares_query_pckt(query, PHP_ARES_PCKT_QUERY, name, name_len, type, dnsclass);
908 ares_query(ares->channel, name, dnsclass, type, php_ares_callback_func, query);
909 }
910 /* }}} */
911
912 /* {{{ proto resource ares_send(resource ares, mixed callback, string buf)
913 Send custom query */
914 static PHP_FUNCTION(ares_send)
915 {
916 zval *rsrc, *cb = NULL;
917 php_ares *ares;
918 php_ares_query *query;
919 char *buf;
920 int len;
921
922 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s", &rsrc, &cb, &buf, &len)) {
923 RETURN_FALSE;
924 }
925 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
926
927 if (cb && !zend_is_callable(cb, 0, NULL)) {
928 RETURN_ARES_CB_ERROR("second");
929 }
930
931 query = php_ares_query_ctor(NULL, PHP_ARES_CB_STD, ares, cb);
932 php_ares_query_rsrc(query, return_value);
933 php_ares_query_pckt(query, PHP_ARES_PCKT_SEND, buf, len);
934 ares_send(ares->channel, (const unsigned char *) buf, len, php_ares_callback_func, query);
935 }
936 /* }}} */
937
938 /* {{{ proto resource ares_gethostbyname(resource ares, mixed callback, string name[, int family = AF_INET])
939 Get host by name */
940 static PHP_FUNCTION(ares_gethostbyname)
941 {
942 zval *rsrc, *cb = NULL;
943 php_ares *ares;
944 php_ares_query *query;
945 char *name;
946 int name_len;
947 long family = AF_INET;
948
949 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &name, &name_len, &family)) {
950 RETURN_FALSE;
951 }
952 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
953
954 if (cb && !zend_is_callable(cb, 0, NULL)) {
955 RETURN_ARES_CB_ERROR("second");
956 }
957
958 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
959 php_ares_query_rsrc(query, return_value);
960 php_ares_query_pckt(query, PHP_ARES_PCKT_HNAME, name, name_len, family);
961 ares_gethostbyname(ares->channel, name, family, php_ares_host_callback_func, query);
962 }
963 /* }}} */
964
965 /* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
966 Get host by address */
967 static PHP_FUNCTION(ares_gethostbyaddr)
968 {
969 zval *rsrc, *cb = NULL;
970 php_ares *ares;
971 php_ares_query *query;
972 char *addr;
973 int addr_len;
974 long family = AF_INET;
975 void *sa;
976 int sa_len;
977
978 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|l", &rsrc, &cb, &addr, &addr_len, &family)) {
979 RETURN_FALSE;
980 }
981 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
982
983 if (cb && !zend_is_callable(cb, 0, NULL)) {
984 PHP_ARES_CB_ERROR("second");
985 RETURN_FALSE;
986 }
987
988 switch (family) {
989 case AF_INET:
990 sa = emalloc(sa_len = sizeof(struct in_addr));
991 break;
992 case AF_INET6:
993 sa = emalloc(sa_len = sizeof(struct in6_addr));
994 break;
995 default:
996 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
997 RETURN_FALSE;
998 break;
999 }
1000
1001 if (1 > inet_pton(family, addr, sa)) {
1002 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1003 RETVAL_FALSE;
1004 } else {
1005 query = php_ares_query_ctor(NULL, PHP_ARES_CB_HOST, ares, cb);
1006 php_ares_query_rsrc(query, return_value);
1007 php_ares_query_pckt(query, PHP_ARES_PCKT_HADDR, addr, addr_len, family);
1008 ares_gethostbyaddr(ares->channel, sa, sa_len, family, php_ares_host_callback_func, query);
1009 }
1010 efree(sa);
1011 }
1012 /* }}} */
1013
1014 #ifdef HAVE_ARES_GETNAMEINFO
1015 /* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
1016 Get name info */
1017 static PHP_FUNCTION(ares_getnameinfo)
1018 {
1019 zval *rsrc, *cb = NULL;
1020 php_ares *ares;
1021 php_ares_query *query;
1022 char *addr;
1023 int addr_len;
1024 long flags, port = 0, family = AF_INET;
1025 struct sockaddr *sa;
1026 struct sockaddr_in *in;
1027 struct sockaddr_in6 *in6;
1028 int sa_len;
1029
1030 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!ls|ll", &rsrc, &cb, &flags, &addr, &addr_len, &family, &port)) {
1031 RETURN_FALSE;
1032 }
1033 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1034
1035 if (cb && !zend_is_callable(cb, 0, NULL)) {
1036 PHP_ARES_CB_ERROR("second");
1037 RETURN_FALSE;
1038 }
1039
1040 RETVAL_TRUE;
1041 switch (family) {
1042 case AF_INET:
1043 in = ecalloc(1, sa_len = sizeof(struct sockaddr_in));
1044 in->sin_family = AF_INET;
1045 in->sin_port = htons((unsigned short) port);
1046 if (1 > inet_pton(in->sin_family, addr, &in->sin_addr)) {
1047 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1048 RETVAL_FALSE;
1049 }
1050 sa = (struct sockaddr *) in;
1051 break;
1052 case AF_INET6:
1053 in6 = ecalloc(1, sa_len = sizeof(struct sockaddr_in6));
1054 in6->sin6_family = AF_INET6;
1055 in6->sin6_port = htons((unsigned short) port);
1056 if (1 > inet_pton(in6->sin6_family, addr, &in6->sin6_addr)) {
1057 php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
1058 RETVAL_FALSE;
1059 }
1060 sa = (struct sockaddr *) in6;
1061 break;
1062 default:
1063 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither AF_INET nor AF_INET6");
1064 RETURN_FALSE;
1065 break;
1066 }
1067
1068 if (Z_BVAL_P(return_value)) {
1069 query = php_ares_query_ctor(NULL, PHP_ARES_CB_NINFO, ares, cb);
1070 php_ares_query_rsrc(query, return_value);
1071 php_ares_query_pckt(query, PHP_ARES_PCKT_NINFO, flags, addr, addr_len, family, port);
1072 ares_getnameinfo(ares->channel, sa, sa_len, flags, php_ares_nameinfo_callback_func, query);
1073 }
1074 efree(sa);
1075 }
1076 /* }}} */
1077 #endif
1078
1079 /* {{{ proto mixed ares_result(resource query, int &errno, string &error)
1080 Check a query for its result */
1081 static PHP_FUNCTION(ares_result)
1082 {
1083 zval *rsrc, *zerrno = NULL, *zerror = NULL;
1084 php_ares_query *query;
1085
1086 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|zz", &rsrc, &zerrno, &zerror)) {
1087 RETURN_FALSE;
1088 }
1089 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1090
1091 if (zerrno) {
1092 zval_dtor(zerrno);
1093 ZVAL_LONG(zerrno, query->error);
1094 }
1095 if (zerror) {
1096 zval_dtor(zerror);
1097 ZVAL_NULL(zerror);
1098 }
1099
1100 switch (query->error) {
1101 case 0:
1102 switch (query->type) {
1103 case PHP_ARES_CB_STD:
1104 RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
1105 break;
1106 case PHP_ARES_CB_HOST:
1107 object_init(return_value);
1108 php_ares_hostent_to_struct(&query->result.host, HASH_OF(return_value));
1109 break;
1110 case PHP_ARES_CB_NINFO:
1111 object_init(return_value);
1112 add_property_string(return_value, "node", query->result.ninfo.node ? query->result.ninfo.node : "", 1);
1113 add_property_string(return_value, "service", query->result.ninfo.service ? query->result.ninfo.service : "", 1);
1114 break;
1115 }
1116 break;
1117 case -1:
1118 RETVAL_FALSE;
1119 break;
1120 default:
1121 if (zerror) {
1122 #ifdef HAVE_OLD_ARES_STRERROR
1123 char *__tmp = NULL;
1124 const char *__err = ares_strerror(query->error, &__tmp);
1125 ZVAL_STRING(zerror, estrdup(__err), 0);
1126 if (__tmp) ares_free_errmem(__tmp);
1127 #else
1128 ZVAL_STRING(zerror, estrdup(ares_strerror(query->error)), 0);
1129 #endif
1130 }
1131 RETVAL_FALSE;
1132 break;
1133 }
1134 }
1135 /* }}} */
1136
1137 /* {{{ proto object ares_packet(resource query)
1138 Check a query for its question packet */
1139 static PHP_FUNCTION(ares_packet)
1140 {
1141 zval *rsrc, *prop;
1142 php_ares_query *query;
1143
1144 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1145 RETURN_FALSE;
1146 }
1147 ZEND_FETCH_RESOURCE(query, php_ares_query *, &rsrc, -1, PHP_ARES_QUERY_LE_NAME, le_ares_query);
1148
1149 object_init(return_value);
1150 add_property_long(return_value, "type", query->packet.type);
1151 add_property_null(return_value, "search");
1152 add_property_null(return_value, "query");
1153 add_property_null(return_value, "send");
1154 add_property_null(return_value, "gethostbyname");
1155 add_property_null(return_value, "gethostbyaddr");
1156 add_property_null(return_value, "getnameinfo");
1157 MAKE_STD_ZVAL(prop);
1158
1159 switch (query->packet.type) {
1160 case PHP_ARES_PCKT_SEARCH:
1161 object_init(prop);
1162 add_property_stringl(prop, "name", query->packet.data.search.name, query->packet.data.search.name_len, 1);
1163 add_property_long(prop, "type", query->packet.data.search.type);
1164 add_property_long(prop, "dnsclass", query->packet.data.search.dnsclass);
1165 add_property_zval(return_value, "search", prop);
1166 break;
1167
1168 case PHP_ARES_PCKT_QUERY:
1169 object_init(prop);
1170 add_property_stringl(prop, "name", query->packet.data.query.name, query->packet.data.query.name_len, 1);
1171 add_property_long(prop, "type", query->packet.data.query.type);
1172 add_property_long(prop, "dnsclass", query->packet.data.query.dnsclass);
1173 add_property_zval(return_value, "query", prop);
1174 break;
1175
1176 case PHP_ARES_PCKT_SEND:
1177 ZVAL_STRINGL(prop, query->packet.data.send.buf, query->packet.data.send.len, 1);
1178 add_property_zval(return_value, "send", prop);
1179 break;
1180
1181 case PHP_ARES_PCKT_HNAME:
1182 object_init(prop);
1183 add_property_stringl(prop, "name", query->packet.data.hname.name, query->packet.data.hname.name_len, 1);
1184 add_property_long(prop, "family", query->packet.data.hname.family);
1185 add_property_zval(return_value, "gethostbyname", prop);
1186 break;
1187
1188 case PHP_ARES_PCKT_HADDR:
1189 object_init(prop);
1190 add_property_stringl(prop, "addr", query->packet.data.haddr.addr, query->packet.data.haddr.addr_len, 1);
1191 add_property_long(prop, "family", query->packet.data.haddr.family);
1192 add_property_zval(return_value, "gethostbyaddr", prop);
1193 break;
1194
1195 case PHP_ARES_PCKT_NINFO:
1196 object_init(prop);
1197 add_property_long(prop, "flags", query->packet.data.ninfo.flags);
1198 add_property_stringl(prop, "addr", query->packet.data.ninfo.addr, query->packet.data.ninfo.addr_len, 1);
1199 add_property_long(prop, "family", query->packet.data.ninfo.family);
1200 add_property_long(prop, "port", query->packet.data.ninfo.port);
1201 add_property_zval(return_value, "getnameinfo", prop);
1202 break;
1203 }
1204
1205 zval_ptr_dtor(&prop);
1206 }
1207 /* }}} */
1208
1209 #ifdef HAVE_ARES_CANCEL
1210 /* {{{ proto void ares_cancel(resource ares)
1211 Cancel pending queries */
1212 static PHP_FUNCTION(ares_cancel)
1213 {
1214 zval *rsrc;
1215 php_ares *ares;
1216
1217 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc)) {
1218 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1219 ares_cancel(ares->channel);
1220 }
1221 }
1222 /* }}} */
1223 #endif
1224
1225 /* {{{ proto void ares_process_all(resource ares[, int max_timeout_ms])
1226 Process all pending queries */
1227 static PHP_FUNCTION(ares_process_all)
1228 {
1229 zval *rsrc;
1230 php_ares *ares;
1231 long max_timeout = -1;
1232
1233 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1234 RETURN_FALSE;
1235 }
1236 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1237
1238 while (php_ares_process(ares, max_timeout));
1239 }
1240 /* }}} */
1241
1242 /* {{{ proto bool ares_process_once(resource ares[, int max_timout_ms])
1243 Process once and return whether it should be called again */
1244 static PHP_FUNCTION(ares_process_once)
1245 {
1246 zval *rsrc;
1247 php_ares *ares;
1248 long max_timeout = -1;
1249
1250 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1251 RETURN_FALSE;
1252 }
1253 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1254
1255 RETVAL_BOOL(php_ares_process(ares, max_timeout));
1256 }
1257 /* }}} */
1258
1259 /* {{{ proto void ares_process(resource ares, array read, array write)
1260 Process call */
1261 static PHP_FUNCTION(ares_process)
1262 {
1263 zval *rsrc, *read = NULL, *write = NULL;
1264 fd_set R, W;
1265 php_ares *ares;
1266
1267 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a!a!", &rsrc, &read, &write)) {
1268 RETURN_FALSE;
1269 }
1270 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1271
1272 FD_ZERO(&R);
1273 FD_ZERO(&W);
1274
1275 php_ares_extract_fds(read, write, &R, &W);
1276 ares_process(ares->channel, &R, &W);
1277 }
1278 /* }}} */
1279
1280 /* proto bool ares_select(array &read, array &write, int timeout_ms)
1281 Select call */
1282 static PHP_FUNCTION(ares_select)
1283 {
1284 zval *read = NULL, *write = NULL;
1285 fd_set R, W;
1286 int nfds;
1287 long timeout;
1288 struct timeval tv;
1289
1290 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aal", &read, &write, &timeout)) {
1291 RETURN_FALSE;
1292 }
1293
1294 if (timeout) {
1295 tv.tv_sec = timeout / 1000;
1296 tv.tv_usec = timeout % (timeout * 1000);
1297 } else {
1298 tv.tv_sec = 1;
1299 tv.tv_usec = 0;
1300 }
1301
1302 FD_ZERO(&R);
1303 FD_ZERO(&W);
1304
1305 nfds = php_ares_extract_fds(read, write, &R, &W);
1306 if (-1 < select(nfds, &R, &W, NULL, &tv)) {
1307 zend_hash_clean(Z_ARRVAL_P(read));
1308 zend_hash_clean(Z_ARRVAL_P(write));
1309 php_ares_publish_fds(&R, &W, read, write);
1310 RETURN_TRUE;
1311 }
1312 RETURN_FALSE;
1313 }
1314 /* }}} */
1315
1316 /* proto int ares_timeout(resource ares[, int max_timout_ms])
1317 Get suggested select timeout in ms */
1318 static PHP_FUNCTION(ares_timeout)
1319 {
1320 zval *rsrc;
1321 long max_timeout = -1;
1322 struct timeval tv, *tvptr;
1323 php_ares *ares;
1324
1325 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &rsrc, &max_timeout)) {
1326 RETURN_FALSE;
1327 }
1328 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1329
1330 if ((tvptr = php_ares_timeout(ares, max_timeout, &tv))) {
1331 RETURN_LONG(tvptr->tv_sec * 1000 + tvptr->tv_usec / 1000);
1332 }
1333 RETURN_LONG(0);
1334 }
1335 /* }}} */
1336
1337 /* {{{ proto int ares_fds(resource ares, array &read, array &write)
1338 Get file descriptors */
1339 static PHP_FUNCTION(ares_fds)
1340 {
1341 zval *rsrc, *read, *write;
1342 fd_set R, W;
1343 php_ares *ares;
1344
1345 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzz", &rsrc, &read, &write)) {
1346 RETURN_FALSE;
1347 }
1348 ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
1349
1350 FD_ZERO(&R);
1351 FD_ZERO(&W);
1352
1353 zval_dtor(read);
1354 zval_dtor(write);
1355 array_init(read);
1356 array_init(write);
1357 ares_fds(ares->channel, &R, &W);
1358 RETVAL_LONG(php_ares_publish_fds(&R, &W, read, write));
1359 }
1360 /* }}} */
1361
1362 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor)
1363 {
1364 php_ares *ares = (php_ares *) rsrc->ptr;
1365
1366 ares_destroy(ares->channel);
1367 zend_llist_destroy(&ares->queries);
1368 php_ares_options_dtor(&ares->options);
1369 efree(ares);
1370 }
1371
1372 static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor)
1373 {
1374 php_ares_query *query = (php_ares_query *) rsrc->ptr;
1375
1376 php_ares_query_dtor(query);
1377 efree(query);
1378 }
1379
1380 /* {{{ PHP_MINIT_FUNCTION */
1381 static PHP_MINIT_FUNCTION(ares)
1382 {
1383 #ifdef HAVE_ARES_VERSION
1384 int ares_version_num;
1385 ares_version(&ares_version_num);
1386
1387 REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
1388 #endif
1389
1390 REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS, CONST_PERSISTENT|CONST_CS);
1391 REGISTER_LONG_CONSTANT("ARES_ENODATA", ARES_ENODATA, CONST_PERSISTENT|CONST_CS);
1392 REGISTER_LONG_CONSTANT("ARES_EFORMERR", ARES_EFORMERR, CONST_PERSISTENT|CONST_CS);
1393 REGISTER_LONG_CONSTANT("ARES_ESERVFAIL", ARES_ESERVFAIL, CONST_PERSISTENT|CONST_CS);
1394 REGISTER_LONG_CONSTANT("ARES_ENOTFOUND", ARES_ENOTFOUND, CONST_PERSISTENT|CONST_CS);
1395 REGISTER_LONG_CONSTANT("ARES_ENOTIMP", ARES_ENOTIMP, CONST_PERSISTENT|CONST_CS);
1396 REGISTER_LONG_CONSTANT("ARES_EREFUSED", ARES_EREFUSED, CONST_PERSISTENT|CONST_CS);
1397 REGISTER_LONG_CONSTANT("ARES_EBADQUERY", ARES_EBADQUERY, CONST_PERSISTENT|CONST_CS);
1398 REGISTER_LONG_CONSTANT("ARES_EBADNAME", ARES_EBADNAME, CONST_PERSISTENT|CONST_CS);
1399 REGISTER_LONG_CONSTANT("ARES_EBADFAMILY", ARES_EBADFAMILY, CONST_PERSISTENT|CONST_CS);
1400 REGISTER_LONG_CONSTANT("ARES_EBADRESP", ARES_EBADRESP, CONST_PERSISTENT|CONST_CS);
1401 REGISTER_LONG_CONSTANT("ARES_ECONNREFUSED", ARES_ECONNREFUSED, CONST_PERSISTENT|CONST_CS);
1402 REGISTER_LONG_CONSTANT("ARES_ETIMEOUT", ARES_ETIMEOUT, CONST_PERSISTENT|CONST_CS);
1403 REGISTER_LONG_CONSTANT("ARES_EOF", ARES_EOF, CONST_PERSISTENT|CONST_CS);
1404 REGISTER_LONG_CONSTANT("ARES_EFILE", ARES_EFILE, CONST_PERSISTENT|CONST_CS);
1405 REGISTER_LONG_CONSTANT("ARES_ENOMEM", ARES_ENOMEM, CONST_PERSISTENT|CONST_CS);
1406 REGISTER_LONG_CONSTANT("ARES_EDESTRUCTION", ARES_EDESTRUCTION, CONST_PERSISTENT|CONST_CS);
1407 #ifdef ARES_EBADSTR
1408 REGISTER_LONG_CONSTANT("ARES_EBADSTR", ARES_EBADSTR, CONST_PERSISTENT|CONST_CS);
1409 #endif
1410 #ifdef ARES_EBADFLAGS
1411 REGISTER_LONG_CONSTANT("ARES_EBADFLAGS", ARES_EBADFLAGS, CONST_PERSISTENT|CONST_CS);
1412 #endif
1413 #ifdef ARES_ENONAME
1414 REGISTER_LONG_CONSTANT("ARES_ENONAME", ARES_ENONAME, CONST_PERSISTENT|CONST_CS);
1415 #endif
1416 #ifdef ARES_EBADHINTS
1417 REGISTER_LONG_CONSTANT("ARES_EBADHINTS", ARES_EBADHINTS, CONST_PERSISTENT|CONST_CS);
1418 #endif
1419
1420 REGISTER_LONG_CONSTANT("ARES_FLAG_USEVC", ARES_FLAG_USEVC, CONST_PERSISTENT|CONST_CS);
1421 REGISTER_LONG_CONSTANT("ARES_FLAG_PRIMARY", ARES_FLAG_PRIMARY, CONST_PERSISTENT|CONST_CS);
1422 REGISTER_LONG_CONSTANT("ARES_FLAG_IGNTC", ARES_FLAG_IGNTC, CONST_PERSISTENT|CONST_CS);
1423 REGISTER_LONG_CONSTANT("ARES_FLAG_NORECURSE", ARES_FLAG_NORECURSE, CONST_PERSISTENT|CONST_CS);
1424 REGISTER_LONG_CONSTANT("ARES_FLAG_STAYOPEN", ARES_FLAG_STAYOPEN, CONST_PERSISTENT|CONST_CS);
1425 REGISTER_LONG_CONSTANT("ARES_FLAG_NOSEARCH", ARES_FLAG_NOSEARCH, CONST_PERSISTENT|CONST_CS);
1426 REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES, CONST_PERSISTENT|CONST_CS);
1427 REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP, CONST_PERSISTENT|CONST_CS);
1428
1429 /*
1430 * Address Family Constants
1431 */
1432 REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET, CONST_PERSISTENT|CONST_CS);
1433 REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6, CONST_PERSISTENT|CONST_CS);
1434
1435 /*
1436 * Name Info constants
1437 */
1438 #ifdef ARES_NI_NOFQDN
1439 REGISTER_LONG_CONSTANT("ARES_NI_NOFQDN", ARES_NI_NOFQDN, CONST_PERSISTENT|CONST_CS);
1440 #endif
1441 #ifdef ARES_NI_NUMERICHOST
1442 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICHOST", ARES_NI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1443 #endif
1444 #ifdef ARES_NI_NAMEREQD
1445 REGISTER_LONG_CONSTANT("ARES_NI_NAMEREQD", ARES_NI_NAMEREQD, CONST_PERSISTENT|CONST_CS);
1446 #endif
1447 #ifdef ARES_NI_NUMERICSERV
1448 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSERV", ARES_NI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1449 #endif
1450 #ifdef ARES_NI_DGRAM
1451 REGISTER_LONG_CONSTANT("ARES_NI_DGRAM", ARES_NI_DGRAM, CONST_PERSISTENT|CONST_CS);
1452 #endif
1453 #ifdef ARES_NI_TCP
1454 REGISTER_LONG_CONSTANT("ARES_NI_TCP", ARES_NI_TCP, CONST_PERSISTENT|CONST_CS);
1455 #endif
1456 #ifdef ARES_NI_UDP
1457 REGISTER_LONG_CONSTANT("ARES_NI_UDP", ARES_NI_UDP, CONST_PERSISTENT|CONST_CS);
1458 #endif
1459 #ifdef ARES_NI_SCTP
1460 REGISTER_LONG_CONSTANT("ARES_NI_SCTP", ARES_NI_SCTP, CONST_PERSISTENT|CONST_CS);
1461 #endif
1462 #ifdef ARES_NI_DCCP
1463 REGISTER_LONG_CONSTANT("ARES_NI_DCCP", ARES_NI_DCCP, CONST_PERSISTENT|CONST_CS);
1464 #endif
1465 #ifdef ARES_NI_NUMERICSCOPE
1466 REGISTER_LONG_CONSTANT("ARES_NI_NUMERICSCOPE", ARES_NI_NUMERICSCOPE, CONST_PERSISTENT|CONST_CS);
1467 #endif
1468 #ifdef ARES_NI_LOOKUPHOST
1469 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPHOST", ARES_NI_LOOKUPHOST, CONST_PERSISTENT|CONST_CS);
1470 #endif
1471 #ifdef ARES_NI_LOOKUPSERVICE
1472 REGISTER_LONG_CONSTANT("ARES_NI_LOOKUPSERVICE", ARES_NI_LOOKUPSERVICE, CONST_PERSISTENT|CONST_CS);
1473 #endif
1474 #ifdef ARES_NI_IDN
1475 REGISTER_LONG_CONSTANT("ARES_NI_IDN", ARES_NI_IDN, CONST_PERSISTENT|CONST_CS);
1476 #endif
1477 #ifdef ARES_NI_IDN_ALLOW_UNASSIGNED
1478 REGISTER_LONG_CONSTANT("ARES_NI_IDN_ALLOW_UNASSIGNED", ARES_NI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1479 #endif
1480 #ifdef ARES_NI_IDN_USE_STD
1481 REGISTER_LONG_CONSTANT("ARES_NI_IDN_USE_STD", ARES_NI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1482 #endif
1483
1484 /*
1485 * Address Info constants
1486 */
1487 #ifdef ARES_AI_CANONNAME
1488 REGISTER_LONG_CONSTANT("ARES_AI_CANONNAME", ARES_AI_CANONNAME, CONST_PERSISTENT|CONST_CS);
1489 #endif
1490 #ifdef ARES_AI_NUMERICHOST
1491 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICHOST", ARES_AI_NUMERICHOST, CONST_PERSISTENT|CONST_CS);
1492 #endif
1493 #ifdef ARES_AI_PASSIVE
1494 REGISTER_LONG_CONSTANT("ARES_AI_PASSIVE", ARES_AI_PASSIVE, CONST_PERSISTENT|CONST_CS);
1495 #endif
1496 #ifdef ARES_AI_NUMERICSERV
1497 REGISTER_LONG_CONSTANT("ARES_AI_NUMERICSERV", ARES_AI_NUMERICSERV, CONST_PERSISTENT|CONST_CS);
1498 #endif
1499 #ifdef ARES_AI_V
1500 REGISTER_LONG_CONSTANT("ARES_AI_V", ARES_AI_V, CONST_PERSISTENT|CONST_CS);
1501 #endif
1502 #ifdef ARES_AI_ALL
1503 REGISTER_LONG_CONSTANT("ARES_AI_ALL", ARES_AI_ALL, CONST_PERSISTENT|CONST_CS);
1504 #endif
1505 #ifdef ARES_AI_ADDRCONFIG
1506 REGISTER_LONG_CONSTANT("ARES_AI_ADDRCONFIG", ARES_AI_ADDRCONFIG, CONST_PERSISTENT|CONST_CS);
1507 #endif
1508 #ifdef ARES_AI_IDN
1509 REGISTER_LONG_CONSTANT("ARES_AI_IDN", ARES_AI_IDN, CONST_PERSISTENT|CONST_CS);
1510 #endif
1511 #ifdef ARES_AI_IDN_ALLOW_UNASSIGNED
1512 REGISTER_LONG_CONSTANT("ARES_AI_IDN_ALLOW_UNASSIGNED", ARES_AI_IDN_ALLOW_UNASSIGNED, CONST_PERSISTENT|CONST_CS);
1513 #endif
1514 #ifdef ARES_AI_IDN_USE_STD
1515 REGISTER_LONG_CONSTANT("ARES_AI_IDN_USE_STD", ARES_AI_IDN_USE_STD, CONST_PERSISTENT|CONST_CS);
1516 #endif
1517 #ifdef ARES_AI_CANONIDN
1518 REGISTER_LONG_CONSTANT("ARES_AI_CANONIDN", ARES_AI_CANONIDN, CONST_PERSISTENT|CONST_CS);
1519 #endif
1520 #ifdef ARES_AI_MASK
1521 REGISTER_LONG_CONSTANT("ARES_AI_MASK", ARES_AI_MASK, CONST_PERSISTENT|CONST_CS);
1522 #endif
1523 #ifdef ARES_GETSOCK_MAXNUM
1524 REGISTER_LONG_CONSTANT("ARES_GETSOCK_MAXNUM", ARES_GETSOCK_MAXNUM, CONST_PERSISTENT|CONST_CS);
1525 #endif
1526
1527 /*
1528 * ns_t (type) constants (arpa/nameser.h)
1529 */
1530
1531 /* (1) Host address. */
1532 REGISTER_LONG_CONSTANT("ARES_T_A", ns_t_a, CONST_CS|CONST_PERSISTENT);
1533 /* (2) Authoritative server. */
1534 REGISTER_LONG_CONSTANT("ARES_T_NS", ns_t_ns, CONST_CS|CONST_PERSISTENT);
1535 /* (3) Mail destination. */
1536 REGISTER_LONG_CONSTANT("ARES_T_MD", ns_t_md, CONST_CS|CONST_PERSISTENT);
1537 /* (4) Mail forwarder. */
1538 REGISTER_LONG_CONSTANT("ARES_T_MF", ns_t_mf, CONST_CS|CONST_PERSISTENT);
1539 /* (5) Canonical name. */
1540 REGISTER_LONG_CONSTANT("ARES_T_CNAME", ns_t_cname, CONST_CS|CONST_PERSISTENT);
1541 /* (6) Start of authority zone. */
1542 REGISTER_LONG_CONSTANT("ARES_T_SOA", ns_t_soa, CONST_CS|CONST_PERSISTENT);
1543 /* (7) Mailbox domain name. */
1544 REGISTER_LONG_CONSTANT("ARES_T_MB", ns_t_mb, CONST_CS|CONST_PERSISTENT);
1545 /* (8) Mail group member. */
1546 REGISTER_LONG_CONSTANT("ARES_T_MG", ns_t_mg, CONST_CS|CONST_PERSISTENT);
1547 /* (9) Mail rename name. */
1548 REGISTER_LONG_CONSTANT("ARES_T_MR", ns_t_mr, CONST_CS|CONST_PERSISTENT);
1549 /* (10) Null resource record. */
1550 REGISTER_LONG_CONSTANT("ARES_T_NULL", ns_t_null, CONST_CS|CONST_PERSISTENT);
1551 /* (11) Well known service. */
1552 REGISTER_LONG_CONSTANT("ARES_T_WKS", ns_t_wks, CONST_CS|CONST_PERSISTENT);
1553 /* (12) Domain name pointer. */
1554 REGISTER_LONG_CONSTANT("ARES_T_PTR", ns_t_ptr, CONST_CS|CONST_PERSISTENT);
1555 /* (13) Host information. */
1556 REGISTER_LONG_CONSTANT("ARES_T_HINFO", ns_t_hinfo, CONST_CS|CONST_PERSISTENT);
1557 /* (14) Mailbox information. */
1558 REGISTER_LONG_CONSTANT("ARES_T_MINFO", ns_t_minfo, CONST_CS|CONST_PERSISTENT);
1559 /* (15) Mail routing information. */
1560 REGISTER_LONG_CONSTANT("ARES_T_MX", ns_t_mx, CONST_CS|CONST_PERSISTENT);
1561 /* (16) Text strings. */
1562 REGISTER_LONG_CONSTANT("ARES_T_TXT", ns_t_txt, CONST_CS|CONST_PERSISTENT);
1563 /* (17) Responsible person. */
1564 REGISTER_LONG_CONSTANT("ARES_T_RP", ns_t_rp, CONST_CS|CONST_PERSISTENT);
1565 /* (18) AFS cell database. */
1566 REGISTER_LONG_CONSTANT("ARES_T_AFSDB", ns_t_afsdb, CONST_CS|CONST_PERSISTENT);
1567 /* (19) X_25 calling address. */
1568 REGISTER_LONG_CONSTANT("ARES_T_X25", ns_t_x25, CONST_CS|CONST_PERSISTENT);
1569 /* (20) ISDN calling address. */
1570 REGISTER_LONG_CONSTANT("ARES_T_ISDN", ns_t_isdn, CONST_CS|CONST_PERSISTENT);
1571 /* (21) Router. */
1572 REGISTER_LONG_CONSTANT("ARES_T_RT", ns_t_rt, CONST_CS|CONST_PERSISTENT);
1573 /* (22) NSAP address. */
1574 REGISTER_LONG_CONSTANT("ARES_T_NSAP", ns_t_nsap, CONST_CS|CONST_PERSISTENT);
1575 /* (23) Reverse NSAP lookup (deprecated). */
1576 /* REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", ns_t_nsap_ptr, CONST_CS|CONST_PERSISTENT); */
1577 /* (24) Security signature. */
1578 REGISTER_LONG_CONSTANT("ARES_T_SIG", ns_t_sig, CONST_CS|CONST_PERSISTENT);
1579 /* (25) Security key. */
1580 REGISTER_LONG_CONSTANT("ARES_T_KEY", ns_t_key, CONST_CS|CONST_PERSISTENT);
1581 /* (26) X.400 mail mapping. */
1582 REGISTER_LONG_CONSTANT("ARES_T_PX", ns_t_px, CONST_CS|CONST_PERSISTENT);
1583 /* (27) Geographical position (withdrawn). */
1584 /* REGISTER_LONG_CONSTANT("ARES_T_GPOS", ns_t_gpos, CONST_CS|CONST_PERSISTENT); */
1585 /* (28) Ip6 Address. */
1586 REGISTER_LONG_CONSTANT("ARES_T_AAAA", ns_t_aaaa, CONST_CS|CONST_PERSISTENT);
1587 /* (29) Location Information. */
1588 REGISTER_LONG_CONSTANT("ARES_T_LOC", ns_t_loc, CONST_CS|CONST_PERSISTENT);
1589 /* (30) Next domain (security). */
1590 REGISTER_LONG_CONSTANT("ARES_T_NXT", ns_t_nxt, CONST_CS|CONST_PERSISTENT);
1591 /* (31) Endpoint identifier. */
1592 REGISTER_LONG_CONSTANT("ARES_T_EID", ns_t_eid, CONST_CS|CONST_PERSISTENT);
1593 /* (32) Nimrod Locator. */
1594 REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", ns_t_nimloc, CONST_CS|CONST_PERSISTENT);
1595 /* (33) Server Selection. */
1596 REGISTER_LONG_CONSTANT("ARES_T_SRV", ns_t_srv, CONST_CS|CONST_PERSISTENT);
1597 /* (34) ATM Address */
1598 REGISTER_LONG_CONSTANT("ARES_T_ATMA", ns_t_atma, CONST_CS|CONST_PERSISTENT);
1599 /* (35) Naming Authority PoinTeR */
1600 REGISTER_LONG_CONSTANT("ARES_T_NAPTR", ns_t_naptr, CONST_CS|CONST_PERSISTENT);
1601 /* (36) Key Exchange */
1602 REGISTER_LONG_CONSTANT("ARES_T_KX", ns_t_kx, CONST_CS|CONST_PERSISTENT);
1603 /* (37) Certification record */
1604 REGISTER_LONG_CONSTANT("ARES_T_CERT", ns_t_cert, CONST_CS|CONST_PERSISTENT);
1605 /* (38) IPv6 address (deprecates AAAA) */
1606 REGISTER_LONG_CONSTANT("ARES_T_A6", ns_t_a6, CONST_CS|CONST_PERSISTENT);
1607 /* (39) Non-terminal DNAME (for IPv6) */
1608 REGISTER_LONG_CONSTANT("ARES_T_DNAME", ns_t_dname, CONST_CS|CONST_PERSISTENT);
1609 /* (40) Kitchen sink (experimentatl) */
1610 REGISTER_LONG_CONSTANT("ARES_T_SINK", ns_t_sink, CONST_CS|CONST_PERSISTENT);
1611 /* (41) EDNS0 option (meta-RR) */
1612 REGISTER_LONG_CONSTANT("ARES_T_OPT", ns_t_opt, CONST_CS|CONST_PERSISTENT);
1613 /* (250) Transaction signature. */
1614 REGISTER_LONG_CONSTANT("ARES_T_TSIG", ns_t_tsig, CONST_CS|CONST_PERSISTENT);
1615 /* (251) Incremental zone transfer. */
1616 REGISTER_LONG_CONSTANT("ARES_T_IXFR", ns_t_ixfr, CONST_CS|CONST_PERSISTENT);
1617 /* (252) Transfer zone of authority. */
1618 REGISTER_LONG_CONSTANT("ARES_T_AXFR", ns_t_axfr, CONST_CS|CONST_PERSISTENT);
1619 /* (253) Transfer mailbox records. */
1620 REGISTER_LONG_CONSTANT("ARES_T_MAILB", ns_t_mailb, CONST_CS|CONST_PERSISTENT);
1621 /* (254) Transfer mail agent records. */
1622 REGISTER_LONG_CONSTANT("ARES_T_MAILA", ns_t_maila, CONST_CS|CONST_PERSISTENT);
1623 /* (255) Wildcard match. */
1624 REGISTER_LONG_CONSTANT("ARES_T_ANY", ns_t_any, CONST_CS|CONST_PERSISTENT);
1625
1626 /*
1627 * ns_c (dnsclass) constants (arpa/nameser.h)
1628 */
1629
1630 /* (1) Internet. */
1631 REGISTER_LONG_CONSTANT("ARES_C_IN", ns_c_in, CONST_CS|CONST_PERSISTENT);
1632 /* (2) unallocated/unsupported. */
1633 /* REGISTER_LONG_CONSTANT("ARES_C_2", ns_c_2, CONST_CS|CONST_PERSISTENT); */
1634 /* (3) MIT Chaos-net. */
1635 REGISTER_LONG_CONSTANT("ARES_C_CHAOS", ns_c_chaos, CONST_CS|CONST_PERSISTENT);
1636 /* (4) MIT Hesiod. */
1637 REGISTER_LONG_CONSTANT("ARES_C_HS", ns_c_hs, CONST_CS|CONST_PERSISTENT);
1638 /* (254) for prereq. sections in update requests */
1639 /* REGISTER_LONG_CONSTANT("ARES_C_NONE", ns_c_none, CONST_CS|CONST_PERSISTENT); */
1640 /* (255) Wildcard match. */
1641 REGISTER_LONG_CONSTANT("ARES_C_ANY", ns_c_any, CONST_CS|CONST_PERSISTENT);
1642
1643 le_ares = zend_register_list_destructors_ex(php_ares_le_dtor, NULL, PHP_ARES_LE_NAME, module_number);
1644 le_ares_query = zend_register_list_destructors_ex(php_ares_query_le_dtor, NULL, PHP_ARES_QUERY_LE_NAME, module_number);
1645
1646 return SUCCESS;
1647 }
1648 /* }}} */
1649
1650 /* {{{ PHP_MINFO_FUNCTION */
1651 static PHP_MINFO_FUNCTION(ares)
1652 {
1653 php_info_print_table_start();
1654 php_info_print_table_header(2, "AsyncResolver support", "enabled");
1655 php_info_print_table_row(2, "Version", PHP_ARES_VERSION);
1656 php_info_print_table_end();
1657
1658 php_info_print_table_start();
1659 php_info_print_table_header(3, "Used Library", "compiled", "linked");
1660 php_info_print_table_row(3,
1661 PHP_ARES_LIBNAME,
1662 #ifdef ARES_VERSION_STR
1663 ARES_VERSION_STR,
1664 #else
1665 "unkown",
1666 #endif
1667 #ifdef HAVE_ARES_VERSION
1668 ares_version(NULL)
1669 #else
1670 "unkown"
1671 #endif
1672 );
1673 php_info_print_table_end();
1674 }
1675 /* }}} */
1676
1677 #ifdef ZEND_ENGINE_2
1678 ZEND_BEGIN_ARG_INFO(ai_ares_select, 0)
1679 ZEND_ARG_PASS_INFO(1)
1680 ZEND_ARG_PASS_INFO(1)
1681 ZEND_ARG_PASS_INFO(0)
1682 ZEND_END_ARG_INFO();
1683
1684 ZEND_BEGIN_ARG_INFO(ai_ares_result, 0)
1685 ZEND_ARG_PASS_INFO(0)
1686 ZEND_ARG_PASS_INFO(1)
1687 ZEND_ARG_PASS_INFO(1)
1688 ZEND_END_ARG_INFO();
1689
1690 ZEND_BEGIN_ARG_INFO(ai_ares_fds, 0)
1691 ZEND_ARG_PASS_INFO(0)
1692 ZEND_ARG_PASS_INFO(1)
1693 ZEND_ARG_PASS_INFO(1)
1694 ZEND_END_ARG_INFO();
1695 #else
1696 static unsigned char ai_ares_select[] = {3, BYREF_FORCE, BYREF_FORCE, BYREF_NONE};
1697 static unsigned char ai_ares_result[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
1698 static unsigned char ai_ares_fds[] = {4, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
1699 #endif
1700
1701 /* {{{ ares_functions[] */
1702 zend_function_entry ares_functions[] = {
1703 #ifdef HAVE_ARES_VERSION
1704 PHP_FE(ares_version, NULL)
1705 #endif
1706 PHP_FE(ares_init, NULL)
1707 PHP_FE(ares_destroy, NULL)
1708 PHP_FE(ares_strerror, NULL)
1709 #ifdef HAVE_ARES_CANCEL
1710 PHP_FE(ares_cancel, NULL)
1711 #endif
1712 PHP_FE(ares_search, NULL)
1713 PHP_FE(ares_query, NULL)
1714 PHP_FE(ares_send, NULL)
1715 PHP_FE(ares_mkquery, NULL)
1716 PHP_FE(ares_gethostbyname, NULL)
1717 PHP_FE(ares_gethostbyaddr, NULL)
1718 #ifdef HAVE_ARES_GETNAMEINFO
1719 PHP_FE(ares_getnameinfo, NULL)
1720 #endif
1721 PHP_FE(ares_result, ai_ares_result)
1722 PHP_FE(ares_packet, NULL)
1723 PHP_FE(ares_process_all, NULL)
1724 PHP_FE(ares_process_once, NULL)
1725 PHP_FE(ares_process, NULL)
1726 PHP_FE(ares_select, ai_ares_select)
1727 PHP_FE(ares_fds, ai_ares_fds)
1728 PHP_FE(ares_timeout, NULL)
1729 {NULL, NULL, NULL}
1730 };
1731 /* }}} */
1732
1733 /* {{{ ares_module_entry */
1734 zend_module_entry ares_module_entry = {
1735 STANDARD_MODULE_HEADER,
1736 "ares",
1737 ares_functions,
1738 PHP_MINIT(ares),
1739 NULL,
1740 NULL,
1741 NULL,
1742 PHP_MINFO(ares),
1743 PHP_ARES_VERSION,
1744 STANDARD_MODULE_PROPERTIES
1745 };
1746 /* }}} */
1747
1748 #ifdef COMPILE_DL_ARES
1749 ZEND_GET_MODULE(ares)
1750 #endif
1751
1752 /*
1753 * Local variables:
1754 * tab-width: 4
1755 * c-basic-offset: 4
1756 * End:
1757 * vim600: noet sw=4 ts=4 fdm=marker
1758 * vim<600: noet sw=4 ts=4
1759 */