fix build with c-ares >= 1.6.1
[m6w6/ext-ares] / ares.c
diff --git a/ares.c b/ares.c
index 6f0342b6e5340c02f97298a52ffed2a73d34e4af..7191268dded77ee009b39f7b881310ce97b38380 100644 (file)
--- a/ares.c
+++ b/ares.c
 #ifdef HAVE_ARPA_NAMESER_H
 #      include <arpa/nameser.h>
 #endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#      include <arpa/nameser_compat.h>
+#endif
 
 #define local inline
 
 #ifndef ZEND_ENGINE_2
-#      define zend_is_callable(a,b,c) 1
+#      define IS_CALLABLE(a,b,c) 1
 #      ifndef ZTS
 #              undef TSRMLS_SET_CTX
 #              define TSRMLS_SET_CTX
 #              define TSRMLS_FETCH_FROM_CTX
 #      endif
 #endif
+#if (PHP_MAJOR_VERSION > 5) || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3))
+#      define ADDREF(z) Z_ADDREF_P(z)
+#      define IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c) TSRMLS_CC)
+#else
+#      define ADDREF(z) ZVAL_ADDREF(z)
+#      define IS_CALLABLE(a,b,c) zend_is_callable((a), (b), (c))
+#endif
 
 #define PHP_ARES_LE_NAME "AsyncResolver"
 #define PHP_ARES_QUERY_LE_NAME "AsyncResolverQuery"
 static int le_ares;
 static int le_ares_query;
 
+static const char *php_ares_C_names[] = {
+       "INVALID",
+       "IN",
+       "CHAOS",
+       "HS",
+       "NONE",
+       "ANY",
+};
+
+static const char *php_ares_T_names[] = {
+       "INVALID",
+       "A",
+       "NS",
+       "MD",
+       "MF",
+       "CNAME",
+       "SOA",
+       "MB",
+       "MG",
+       "MR",
+       "NULL",
+       "WKS",
+       "PTR",
+       "HINFO",
+       "MINFO",
+       "MX",
+       "TXT",
+       "RP",
+       "AFSDB",
+       "X25",
+       "ISDN",
+       "RT",
+       "NSAP",
+       "NSAP_PTR",
+       "SIG",
+       "KEY",
+       "PX",
+       "GPOS",
+       "AAAA",
+       "LOC",
+       "NXT",
+       "EID",
+       "NIMLOC",
+       "SRV",
+       "ATMA",
+       "NAPTR",
+       "KX",
+       "CERT",
+       "A6",
+       "DNAME",
+       "SINK",
+       "OPT",
+       "APL",
+       "TKEY",
+       "TSIG",
+       "IXFR",
+       "AXFR",
+       "MAILB",
+       "MAILA",
+       "ANY",
+       "ZXFR",
+};
+
 #ifdef HAVE_OLD_ARES_STRERROR
 #      define PHP_ARES_ERROR(err) { \
        char *__tmp = NULL; \
@@ -75,6 +148,8 @@ static int le_ares_query;
        PHP_ARES_CB_ERROR(param); \
        RETURN_FALSE
 
+#define PHP_ARES_QUERY_BUFFER_LEN 2<<0xf
+
 /* {{{ typedefs */
 typedef struct _php_ares_options {
        struct ares_options strct;
@@ -109,8 +184,8 @@ typedef union _php_ares_query_packet_data {
        struct {
                char *name;
                int name_len;
-               int type;
-               int dnsclass;
+               long type;
+               long dnsclass;
        } search;
        struct {
                char *name;
@@ -148,6 +223,7 @@ typedef struct _php_ares_query_packet {
 
 typedef union _php_ares_query_result {
        struct {
+               zval *arr;
                char *buf;
                int len;
        } std;
@@ -280,7 +356,7 @@ local php_ares_query *php_ares_query_ctor(php_ares_query *query, php_ares_query_
        query->error = -1;
        
        if (callback) {
-               ZVAL_ADDREF(callback);
+               ADDREF(callback);
                query->callback = callback;
        }
        
@@ -373,6 +449,9 @@ local void php_ares_query_dtor(php_ares_query *query) /* {{{ */
        }
        switch (query->type) {
                case PHP_ARES_CB_STD:
+                       if (query->result.std.arr) {
+                               zval_ptr_dtor(&query->result.std.arr);
+                       }
                        STR_FREE(query->result.std.buf);
                        break;
                case PHP_ARES_CB_HOST:
@@ -427,11 +506,11 @@ local php_ares_options *php_ares_options_ctor(php_ares_options *options, HashTab
                }
                if ((SUCCESS == zend_hash_find(ht, "udp_port", sizeof("udp_port"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
                        options->flags |= ARES_OPT_UDP_PORT;
-                       options->strct.udp_port = Z_LVAL_PP(opt);
+                       options->strct.udp_port = htons((unsigned short) Z_LVAL_PP(opt));
                }
                if ((SUCCESS == zend_hash_find(ht, "tcp_port", sizeof("tcp_port"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_LONG)) {
                        options->flags |= ARES_OPT_TCP_PORT;
-                       options->strct.tcp_port = Z_LVAL_PP(opt);
+                       options->strct.tcp_port = htons((unsigned short) Z_LVAL_PP(opt));
                }
                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)))) {
                        options->strct.servers = ecalloc(i, sizeof(struct in_addr));
@@ -456,7 +535,7 @@ local php_ares_options *php_ares_options_ctor(php_ares_options *options, HashTab
                                }
                        }
                        if (options->strct.ndomains) {
-                               options->flags |= ARES_OPT_SERVERS;
+                               options->flags |= ARES_OPT_DOMAINS;
                        }
                }
                if ((SUCCESS == zend_hash_find(ht, "lookups", sizeof("lookups"), (void *) &opt)) && (Z_TYPE_PP(opt) == IS_STRING)) {
@@ -498,17 +577,193 @@ local void php_ares_options_free(php_ares_options **options) /* {{{ */
 }
 /* }}} */
 
+local PHP_ARES_EXPAND_LEN_TYPE php_ares_skip(const unsigned char *pointer, const unsigned char *abuf, int alen TSRMLS_DC)
+{
+       char *name;
+       int rc;
+       PHP_ARES_EXPAND_LEN_TYPE byte_count;
+
+       /*      NOTE: byte_count is not neccessarily the length of the string,
+               i.e. if there were back references */
+       if (ARES_SUCCESS == (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+               /*fprintf(stderr, "-- skipping %s\n", name);*/
+               ares_free_string(name);
+               return byte_count;
+       }
+       PHP_ARES_ERROR(rc);
+       return -1;
+}
+
+local int php_ares_parse(const unsigned char *abuf, int alen, zval *result TSRMLS_DC) /* {{{ */
+{
+       HEADER *header;
+       PHP_ARES_EXPAND_LEN_TYPE byte_count;
+       const unsigned char *pointer;
+       char *name;
+       int rc, query_count, answer_count;
+
+       convert_to_array(result);
+
+       if (!alen || !abuf || !*abuf) {
+               return SUCCESS;
+       }
+
+       header = (HEADER *) abuf;
+       pointer = abuf + HFIXEDSZ;
+       
+       for (query_count = ntohs(header->qdcount); query_count--; pointer += byte_count + QFIXEDSZ) {
+               if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
+                       return FAILURE;
+               }
+       }
+
+       for (answer_count = ntohs(header->ancount); answer_count-- && pointer < (abuf + alen); ) {
+               uint16_t stmp, type, class;
+               uint32_t ltmp, ttl;
+               zval **entry_ptr, *entry = NULL;
+
+               if (0 > (byte_count = php_ares_skip(pointer, abuf, alen TSRMLS_CC))) {
+                       return FAILURE;
+               }
+
+               pointer += byte_count;
+
+               MAKE_STD_ZVAL(entry);
+               array_init(entry);
+
+               GETSHORT(type, pointer);
+               add_assoc_string(entry, "type", estrdup(php_ares_T_names[type]), 0);
+               GETSHORT(class, pointer);
+               add_assoc_string(entry, "class", estrdup(php_ares_C_names[class]), 0);
+               GETLONG(ttl, pointer);
+               add_assoc_long(entry, "ttl", ttl);
+               GETSHORT(byte_count, pointer);
+#if 0
+               fprintf(stderr, ">> processing %s answer of length %d\n", php_ares_T_names[type], byte_count);
+#endif
+               switch (type) {
+                       case T_A:
+                               spprintf(&name, 0, "%d.%d.%d.%d", pointer[0], pointer[1], pointer[2], pointer[3]);
+                               add_assoc_string(entry, "addr", name, 0);
+                               pointer += byte_count;
+                               break;
+
+                       case T_NS:
+                       case T_PTR:
+                       case T_CNAME:
+                               if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+                                       PHP_ARES_ERROR(rc);
+                                       return FAILURE;
+                               }
+                               pointer += byte_count;
+                               add_assoc_string(entry, "name", name, 1);
+                               ares_free_string(name);
+                               break;
+
+                       case T_MX:
+                               GETSHORT(stmp, pointer);
+                               if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+                                       PHP_ARES_ERROR(rc);
+                                       return FAILURE;
+                               }
+                               pointer += byte_count;
+                               add_assoc_long(entry, "weight", stmp);
+                               add_assoc_string(entry, "name", name, 1);
+                               ares_free_string(name);
+                               break;
+
+                       case T_SRV:
+                               GETSHORT(stmp, pointer);
+                               add_assoc_long(entry, "priority", stmp);
+                               GETSHORT(stmp, pointer);
+                               add_assoc_long(entry, "weight", stmp);
+                               GETSHORT(stmp, pointer);
+                               add_assoc_long(entry, "port", stmp);
+
+                               if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+                                       PHP_ARES_ERROR(rc);
+                                       zval_ptr_dtor(&entry);
+                                       return FAILURE;
+                               }
+                               pointer += byte_count;
+                               add_assoc_string(entry, "name", name, 1);
+                               ares_free_string(name);
+                               break;
+
+                       case T_SOA:
+                               if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+                                       PHP_ARES_ERROR(rc);
+                                       zval_ptr_dtor(&entry);
+                                       return FAILURE;
+                               }
+                               pointer += byte_count;
+                               add_assoc_string(entry, "name", name, 1);
+                               ares_free_string(name);
+
+                               if (ARES_SUCCESS != (rc = ares_expand_name(pointer, abuf, alen, &name, &byte_count))) {
+                                       PHP_ARES_ERROR(rc);
+                                       zval_ptr_dtor(&entry);
+                                       return FAILURE;
+                               }
+                               pointer += byte_count;
+                               add_assoc_string(entry, "mail", name, 1);
+                               ares_free_string(name);
+
+                               GETLONG(ltmp, pointer);
+                               add_assoc_long(entry, "serial", ltmp);
+                               GETLONG(ltmp, pointer);
+                               add_assoc_long(entry, "refresh", ltmp);
+                               GETLONG(ltmp, pointer);
+                               add_assoc_long(entry, "retry", ltmp);
+                               GETLONG(ltmp, pointer);
+                               add_assoc_long(entry, "expire", ltmp);
+                               GETLONG(ltmp, pointer);
+                               add_assoc_long(entry, "minimum-ttl", ltmp);
+                               break;
+
+                       case T_TXT:
+                               for (ltmp = 0; ltmp < byte_count; ltmp += pointer[ltmp] + 1) {
+                                       add_next_index_stringl(entry, (const char *) &pointer[ltmp + 1], pointer[ltmp], 1);
+                               }
+                               pointer += byte_count;
+                               break;
+
+                       default:
+                               zval_ptr_dtor(&entry);
+                               entry = NULL;
+                               pointer += byte_count;
+                               break;
+               }
+
+               if (entry) {
+                       add_next_index_zval(result, entry);
+               }
+       }
+
+       return SUCCESS;
+}
+/* }}} */
+
 /* {{{ callbacks */
-static void php_ares_callback_func(void *aq, int status, unsigned char *abuf, int alen)
+static void php_ares_callback_func_old(void *aq, int status, unsigned char *abuf, int alen)
 {
        php_ares_query *q = (php_ares_query *) aq;
-       zval *params[3], *retval;
+       zval *params[4], *retval, *parsed = NULL;
        TSRMLS_FETCH_FROM_CTX(q->ares->tsrm_ls);
        
        q->error = status;
        if (abuf) {
                q->result.std.buf = estrndup((char *) abuf, alen);
                q->result.std.len = alen;
+               
+               MAKE_STD_ZVAL(parsed);
+               ZVAL_NULL(parsed);
+               if (SUCCESS == php_ares_parse(abuf, alen, parsed)) {
+                       q->result.std.arr = parsed;
+               } else {
+                       zval_ptr_dtor(&parsed);
+                       parsed = NULL;
+               }
        }
        
        if (q->callback) {
@@ -522,19 +777,28 @@ static void php_ares_callback_func(void *aq, int status, unsigned char *abuf, in
                Z_TYPE_P(params[0]) = IS_RESOURCE;
                ZVAL_LONG(params[1], status);
                ZVAL_STRINGL(params[2], (char *) abuf, alen, 1);
-       
+               
+               if (parsed) {
+                       ADDREF(parsed);
+                       params[3] = parsed;
+               }
+               
                q->ares->in_callback = 1;
-               call_user_function(EG(function_table), NULL, q->callback, retval, 3, params TSRMLS_CC);
+               call_user_function(EG(function_table), NULL, q->callback, retval, parsed ? 4 : 3, params TSRMLS_CC);
                q->ares->in_callback = 0;
                
                zval_ptr_dtor(&retval);
                zval_ptr_dtor(&params[0]);
                zval_ptr_dtor(&params[1]);
                zval_ptr_dtor(&params[2]);
+
+               if (parsed) {
+                       zval_ptr_dtor(&params[3]);
+               }
        }
 }
 
-static void php_ares_host_callback_func(void *aq, int status, struct hostent *hostent)
+static void php_ares_host_callback_func_old(void *aq, int status, struct hostent *hostent)
 {
        php_ares_query *q = (php_ares_query *) aq;
        zval *params[3], *retval;
@@ -570,7 +834,7 @@ static void php_ares_host_callback_func(void *aq, int status, struct hostent *ho
 }
 
 #ifdef HAVE_ARES_GETNAMEINFO
-static void php_ares_nameinfo_callback_func(void *aq, int status, char *node, char *service)
+static void php_ares_nameinfo_callback_func_old(void *aq, int status, char *node, char *service)
 {
        php_ares_query *q = (php_ares_query *) aq;
        zval *params[4], *retval;
@@ -618,6 +882,35 @@ static void php_ares_nameinfo_callback_func(void *aq, int status, char *node, ch
        }
 }
 #endif
+
+#if PHP_ARES_NEW_CALLBACK_API
+#      define php_ares_callback_func php_ares_callback_func_new
+static void php_ares_callback_func_new(void *aq, int status, int timeouts, unsigned char *abuf, int alen)
+{
+       php_ares_callback_func_old(aq, status, abuf, alen);
+}
+
+#      define php_ares_host_callback_func php_ares_host_callback_func_new
+static void php_ares_host_callback_func_new(void *aq, int status, int timeouts, struct hostent *hostent)
+{
+       php_ares_host_callback_func_old(aq, status, hostent);
+}
+
+#      ifdef HAVE_ARES_GETNAMEINFO
+#              define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_new
+static void php_ares_nameinfo_callback_func_new(void *aq, int status, int timeouts, char *node, char *service)
+{
+       php_ares_nameinfo_callback_func_old(aq, status, node, service);
+}
+#      endif
+
+#else
+#      define php_ares_callback_func php_ares_callback_func_old
+#      define php_ares_host_callback_func php_ares_host_callback_func_old
+#      ifdef HAVE_ARES_GETNAMEINFO
+#              define php_ares_nameinfo_callback_func php_ares_nameinfo_callback_func_old
+#      endif
+#endif
 /* }}} */
 
 local struct timeval *php_ares_timeout(php_ares *ares, long max_timeout, struct timeval *tv_buf) /* {{{ */
@@ -818,7 +1111,7 @@ static PHP_FUNCTION(ares_mkquery)
                RETURN_FALSE;
        }
        
-       if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, &query_str, &query_len))) {
+       if (ARES_SUCCESS != (err = ares_mkquery(name_str, dnsclass, type, id, rd, (unsigned char **) &query_str, &query_len))) {
                RETURN_ARES_ERROR(err);
        }
        RETVAL_STRINGL(query_str, query_len, 1);
@@ -835,14 +1128,14 @@ static PHP_FUNCTION(ares_search)
        php_ares_query *query;
        char *name;
        int name_len;
-       long dnsclass = ns_c_in, type = ns_t_a;
+       long dnsclass = C_IN, type = T_A;
        
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
                RETURN_FALSE;
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                RETURN_ARES_CB_ERROR("second");
        }
        
@@ -862,14 +1155,14 @@ static PHP_FUNCTION(ares_query)
        php_ares_query *query;
        char *name;
        int name_len;
-       long dnsclass = ns_c_in, type = ns_t_a;
+       long dnsclass = C_IN, type = T_A;
        
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz!s|ll", &rsrc, &cb, &name, &name_len, &type, &dnsclass)) {
                RETURN_FALSE;
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                RETURN_ARES_CB_ERROR("second");
        }
                
@@ -895,7 +1188,7 @@ static PHP_FUNCTION(ares_send)
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                RETURN_ARES_CB_ERROR("second");
        }
        
@@ -922,7 +1215,7 @@ static PHP_FUNCTION(ares_gethostbyname)
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                RETURN_ARES_CB_ERROR("second");
        }
        
@@ -933,7 +1226,7 @@ static PHP_FUNCTION(ares_gethostbyname)
 }
 /* }}} */
 
-/* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = AF_INET])
+/* {{{ proto resource ares_gethostbyaddr(resuorce ares, mixed callback, string address[, int family = ARES_AF_INET])
        Get host by address */
 static PHP_FUNCTION(ares_gethostbyaddr)
 {
@@ -951,7 +1244,7 @@ static PHP_FUNCTION(ares_gethostbyaddr)
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                PHP_ARES_CB_ERROR("second");
                RETURN_FALSE;
        }
@@ -964,7 +1257,7 @@ static PHP_FUNCTION(ares_gethostbyaddr)
                        sa = emalloc(sa_len = sizeof(struct in6_addr));
                        break;
                default:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither AF_INET nor AF_INET6");
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter family is neither ARES_AF_INET nor ARES_AF_INET6");
                        RETURN_FALSE;
                        break;
        }
@@ -983,7 +1276,7 @@ static PHP_FUNCTION(ares_gethostbyaddr)
 /* }}} */
 
 #ifdef HAVE_ARES_GETNAMEINFO
-/* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family[, int port]])
+/* {{{ proto resource ares_getnameinfo(resource ares, mixed callback, int flags, string addr[, int family = ARES_AF_INET[, int port = 0]])
        Get name info */
 static PHP_FUNCTION(ares_getnameinfo)
 {
@@ -1003,7 +1296,7 @@ static PHP_FUNCTION(ares_getnameinfo)
        }
        ZEND_FETCH_RESOURCE(ares, php_ares *, &rsrc, -1, PHP_ARES_LE_NAME, le_ares);
        
-       if (cb && !zend_is_callable(cb, 0, NULL)) {
+       if (cb && !IS_CALLABLE(cb, 0, NULL)) {
                PHP_ARES_CB_ERROR("second");
                RETURN_FALSE;
        }
@@ -1011,9 +1304,9 @@ static PHP_FUNCTION(ares_getnameinfo)
        RETVAL_TRUE;
        switch (family) {
                case AF_INET:
-                       in = emalloc(sa_len = sizeof(struct sockaddr_in));
+                       in = ecalloc(1, sa_len = sizeof(struct sockaddr_in));
                        in->sin_family = AF_INET;
-                       in->sin_port = port;
+                       in->sin_port = htons((unsigned short) port);
                        if (1 > inet_pton(in->sin_family, addr, &in->sin_addr)) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
                                RETVAL_FALSE;
@@ -1021,9 +1314,9 @@ static PHP_FUNCTION(ares_getnameinfo)
                        sa = (struct sockaddr *) in;
                        break;
                case AF_INET6:
-                       in6 = emalloc(sa_len = sizeof(struct sockaddr_in6));
+                       in6 = ecalloc(1, sa_len = sizeof(struct sockaddr_in6));
                        in6->sin6_family = AF_INET6;
-                       in6->sin6_port = port;
+                       in6->sin6_port = htons((unsigned short) port);
                        if (1 > inet_pton(in6->sin6_family, addr, &in6->sin6_addr)) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "inet_pton('%s') failed", addr);
                                RETVAL_FALSE;
@@ -1072,7 +1365,11 @@ static PHP_FUNCTION(ares_result)
                case 0:
                        switch (query->type) {
                                case PHP_ARES_CB_STD:
-                                       RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
+                                       if (query->result.std.arr) {
+                                               RETVAL_ZVAL(query->result.std.arr, 1, 0);
+                                       } else {
+                                               RETVAL_STRINGL(query->result.std.buf, query->result.std.len, 1);
+                                       }
                                        break;
                                case PHP_ARES_CB_HOST:
                                        object_init(return_value);
@@ -1330,117 +1627,6 @@ static PHP_FUNCTION(ares_fds)
 }
 /* }}} */
 
-
-/* {{{ proto array ares_parse_a_reply(string reply)
-       Parse an A reply */
-static PHP_FUNCTION(ares_parse_a_reply)
-{
-       char *buf;
-       int len, err;
-       struct hostent *hostent;
-       
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &len)) {
-               RETURN_FALSE;
-       }
-       
-       if (ARES_SUCCESS != (err = ares_parse_a_reply((const unsigned char *) buf, len, &hostent))) {
-               RETURN_ARES_ERROR(err);
-       }
-       
-       object_init(return_value);
-       php_ares_hostent_to_struct(hostent, HASH_OF(return_value));
-       ares_free_hostent(hostent);
-}
-/* }}} */
-
-#ifdef HAVE_ARES_PARSE_AAAA_REPLY
-/* {{{ proto array ares_parse_aaaa_reply(string reply)
-       Parse an AAAA reply */
-static PHP_FUNCTION(ares_parse_aaaa_reply)
-{
-       char *buf;
-       int len, err;
-       struct hostent *hostent;
-       
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &len)) {
-               RETURN_FALSE;
-       }
-       
-       if (ARES_SUCCESS != (err = ares_parse_aaaa_reply((const unsigned char *) buf, len, &hostent))) {
-               RETURN_ARES_ERROR(err);
-       }
-       
-       object_init(return_value);
-       php_ares_hostent_to_struct(hostent, HASH_OF(return_value));
-       ares_free_hostent(hostent);
-}
-/* }}} */
-#endif
-
-/* {{{ proto array ares_parse_ptr_reply(string reply)
-       Parse a PTR reply */
-static PHP_FUNCTION(ares_parse_ptr_reply)
-{
-       char *buf;
-       int len, err;
-       struct hostent *hostent;
-       
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &len)) {
-               RETURN_FALSE;
-       }
-       
-       if (ARES_SUCCESS != (err = ares_parse_ptr_reply((const unsigned char *) buf, len, NULL, 0, 0, &hostent))) {
-               RETURN_ARES_ERROR(err);
-       }
-       
-       object_init(return_value);
-       php_ares_hostent_to_struct(hostent, HASH_OF(return_value));
-       ares_free_hostent(hostent);
-}
-/* }}} */
-
-/* {{{ proto string ares_expand_name(string name)
-       Expand a DNS encoded name into a human readable dotted string */
-static PHP_FUNCTION(ares_expand_name)
-{
-       char *name_str, *exp_str;
-       int name_len,err;
-       PHP_ARES_EXPAND_LEN_TYPE exp_len;
-       
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
-               RETURN_FALSE;
-       }
-       
-       if (ARES_SUCCESS != (err = ares_expand_name((const unsigned char *) name_str, (const unsigned char *) name_str, name_len, &exp_str, &exp_len))) {
-               RETURN_ARES_ERROR(err);
-       }
-       RETVAL_STRINGL(exp_str, exp_len, 1);
-       ares_free_string(exp_str);
-}
-/* }}} */
-
-#ifdef HAVE_ARES_EXPAND_STRING
-/* {{{ proto string ares_expand_string(string buf)
-       Expand a DNS encoded string into a human readable */
-static PHP_FUNCTION(ares_expand_string)
-{
-       char *buf_str, *exp_str;
-       int buf_len, err;
-       PHP_ARES_EXPAND_LEN_TYPE exp_len;
-       
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf_str, &buf_len)) {
-               RETURN_FALSE;
-       }
-       
-       if (ARES_SUCCESS != (err = ares_expand_string((const unsigned char *) buf_str, (const unsigned char *) buf_str, buf_len, &exp_str, &exp_len))) {
-               RETURN_ARES_ERROR(err);
-       }
-       RETVAL_STRINGL(exp_str, exp_len, 1);
-       ares_free_string(exp_str);
-}
-/* }}} */
-#endif
-
 static ZEND_RSRC_DTOR_FUNC(php_ares_le_dtor)
 {
        php_ares *ares = (php_ares *) rsrc->ptr;
@@ -1462,11 +1648,18 @@ static ZEND_RSRC_DTOR_FUNC(php_ares_query_le_dtor)
 /* {{{ PHP_MINIT_FUNCTION */
 static PHP_MINIT_FUNCTION(ares)
 {
+#ifdef HAVE_ARES_LIBRARY_INIT
+       if (ARES_SUCCESS != ares_library_init(ARES_LIB_INIT_ALL)) {
+               return FAILURE;
+       }
+#endif
 #ifdef HAVE_ARES_VERSION
-       int ares_version_num;
-       ares_version(&ares_version_num);
-       
-       REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
+       {
+               int ares_version_num;
+               ares_version(&ares_version_num);
+
+               REGISTER_LONG_CONSTANT("ARES_VERSION", ares_version_num, CONST_PERSISTENT|CONST_CS);
+       }
 #endif
        
        REGISTER_LONG_CONSTANT("ARES_SUCCESS", ARES_SUCCESS, CONST_PERSISTENT|CONST_CS);
@@ -1508,15 +1701,11 @@ static PHP_MINIT_FUNCTION(ares)
        REGISTER_LONG_CONSTANT("ARES_FLAG_NOALIASES", ARES_FLAG_NOALIASES, CONST_PERSISTENT|CONST_CS);
        REGISTER_LONG_CONSTANT("ARES_FLAG_NOCHECKRESP", ARES_FLAG_NOCHECKRESP, CONST_PERSISTENT|CONST_CS);
        
-       REGISTER_LONG_CONSTANT("ARES_OPT_FLAGS", ARES_OPT_FLAGS, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_TIMEOUT", ARES_OPT_TIMEOUT, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_TRIES", ARES_OPT_TRIES, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_NDOTS", ARES_OPT_NDOTS, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_UDP_PORT", ARES_OPT_UDP_PORT, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_TCP_PORT", ARES_OPT_TCP_PORT, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_SERVERS", ARES_OPT_SERVERS, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_DOMAINS", ARES_OPT_DOMAINS, CONST_PERSISTENT|CONST_CS);
-       REGISTER_LONG_CONSTANT("ARES_OPT_LOOKUPS", ARES_OPT_LOOKUPS, CONST_PERSISTENT|CONST_CS);
+       /*
+        * Address Family Constants
+        */
+       REGISTER_LONG_CONSTANT("ARES_AF_INET", AF_INET, CONST_PERSISTENT|CONST_CS);
+       REGISTER_LONG_CONSTANT("ARES_AF_INET6", AF_INET6, CONST_PERSISTENT|CONST_CS);
        
        /*
         * Name Info constants
@@ -1615,116 +1804,116 @@ static PHP_MINIT_FUNCTION(ares)
         */
 
        /* (1)  Host address.  */
-       REGISTER_LONG_CONSTANT("ARES_T_A", ns_t_a, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_A", T_A, CONST_CS|CONST_PERSISTENT);
        /* (2)  Authoritative server.  */
-       REGISTER_LONG_CONSTANT("ARES_T_NS", ns_t_ns, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NS", T_NS, CONST_CS|CONST_PERSISTENT);
        /* (3)  Mail destination.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MD", ns_t_md, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MD", T_MD, CONST_CS|CONST_PERSISTENT);
        /* (4)  Mail forwarder.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MF", ns_t_mf, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MF", T_MF, CONST_CS|CONST_PERSISTENT);
        /* (5)  Canonical name.  */
-       REGISTER_LONG_CONSTANT("ARES_T_CNAME", ns_t_cname, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_CNAME", T_CNAME, CONST_CS|CONST_PERSISTENT);
        /* (6)  Start of authority zone.  */
-       REGISTER_LONG_CONSTANT("ARES_T_SOA", ns_t_soa, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_SOA", T_SOA, CONST_CS|CONST_PERSISTENT);
        /* (7)  Mailbox domain name.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MB", ns_t_mb, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MB", T_MB, CONST_CS|CONST_PERSISTENT);
        /* (8)  Mail group member.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MG", ns_t_mg, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MG", T_MG, CONST_CS|CONST_PERSISTENT);
        /* (9)  Mail rename name.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MR", ns_t_mr, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MR", T_MR, CONST_CS|CONST_PERSISTENT);
        /* (10)  Null resource record.  */
-       REGISTER_LONG_CONSTANT("ARES_T_NULL", ns_t_null, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NULL", T_NULL, CONST_CS|CONST_PERSISTENT);
        /* (11)  Well known service.  */
-       REGISTER_LONG_CONSTANT("ARES_T_WKS", ns_t_wks, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_WKS", T_WKS, CONST_CS|CONST_PERSISTENT);
        /* (12)  Domain name pointer.  */
-       REGISTER_LONG_CONSTANT("ARES_T_PTR", ns_t_ptr, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_PTR", T_PTR, CONST_CS|CONST_PERSISTENT);
        /* (13)  Host information.  */
-       REGISTER_LONG_CONSTANT("ARES_T_HINFO", ns_t_hinfo, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_HINFO", T_HINFO, CONST_CS|CONST_PERSISTENT);
        /* (14)  Mailbox information.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MINFO", ns_t_minfo, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MINFO", T_MINFO, CONST_CS|CONST_PERSISTENT);
        /* (15)  Mail routing information.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MX", ns_t_mx, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MX", T_MX, CONST_CS|CONST_PERSISTENT);
        /* (16)  Text strings.  */
-       REGISTER_LONG_CONSTANT("ARES_T_TXT", ns_t_txt, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_TXT", T_TXT, CONST_CS|CONST_PERSISTENT);
        /* (17)  Responsible person.  */
-       REGISTER_LONG_CONSTANT("ARES_T_RP", ns_t_rp, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_RP", T_RP, CONST_CS|CONST_PERSISTENT);
        /* (18)  AFS cell database.  */
-       REGISTER_LONG_CONSTANT("ARES_T_AFSDB", ns_t_afsdb, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_AFSDB", T_AFSDB, CONST_CS|CONST_PERSISTENT);
        /* (19)  X_25 calling address.  */
-       REGISTER_LONG_CONSTANT("ARES_T_X25", ns_t_x25, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_X25", T_X25, CONST_CS|CONST_PERSISTENT);
        /* (20)  ISDN calling address.  */
-       REGISTER_LONG_CONSTANT("ARES_T_ISDN", ns_t_isdn, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_ISDN", T_ISDN, CONST_CS|CONST_PERSISTENT);
        /* (21)  Router.  */
-       REGISTER_LONG_CONSTANT("ARES_T_RT", ns_t_rt, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_RT", T_RT, CONST_CS|CONST_PERSISTENT);
        /* (22)  NSAP address.  */
-       REGISTER_LONG_CONSTANT("ARES_T_NSAP", ns_t_nsap, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NSAP", T_NSAP, CONST_CS|CONST_PERSISTENT);
        /* (23)  Reverse NSAP lookup (deprecated).  */
-       /* REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", ns_t_nsap_ptr, CONST_CS|CONST_PERSISTENT); */
+       /* REGISTER_LONG_CONSTANT("ARES_T_NSAP_PTR", T_NSAP_PTR, CONST_CS|CONST_PERSISTENT); */
        /* (24)  Security signature.  */
-       REGISTER_LONG_CONSTANT("ARES_T_SIG", ns_t_sig, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_SIG", T_SIG, CONST_CS|CONST_PERSISTENT);
        /* (25)  Security key.  */
-       REGISTER_LONG_CONSTANT("ARES_T_KEY", ns_t_key, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_KEY", T_KEY, CONST_CS|CONST_PERSISTENT);
        /* (26)  X.400 mail mapping.  */
-       REGISTER_LONG_CONSTANT("ARES_T_PX", ns_t_px, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_PX", T_PX, CONST_CS|CONST_PERSISTENT);
        /* (27)  Geographical position (withdrawn).  */
-       /* REGISTER_LONG_CONSTANT("ARES_T_GPOS", ns_t_gpos, CONST_CS|CONST_PERSISTENT); */
+       /* REGISTER_LONG_CONSTANT("ARES_T_GPOS", T_GPOS, CONST_CS|CONST_PERSISTENT); */
        /* (28)  Ip6 Address.  */
-       REGISTER_LONG_CONSTANT("ARES_T_AAAA", ns_t_aaaa, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_AAAA", T_AAAA, CONST_CS|CONST_PERSISTENT);
        /* (29)  Location Information.  */
-       REGISTER_LONG_CONSTANT("ARES_T_LOC", ns_t_loc, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_LOC", T_LOC, CONST_CS|CONST_PERSISTENT);
        /* (30)  Next domain (security).  */
-       REGISTER_LONG_CONSTANT("ARES_T_NXT", ns_t_nxt, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NXT", T_NXT, CONST_CS|CONST_PERSISTENT);
        /* (31)  Endpoint identifier.  */
-       REGISTER_LONG_CONSTANT("ARES_T_EID", ns_t_eid, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_EID", T_EID, CONST_CS|CONST_PERSISTENT);
        /* (32)  Nimrod Locator.  */
-       REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", ns_t_nimloc, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NIMLOC", T_NIMLOC, CONST_CS|CONST_PERSISTENT);
        /* (33)  Server Selection.  */
-       REGISTER_LONG_CONSTANT("ARES_T_SRV", ns_t_srv, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_SRV", T_SRV, CONST_CS|CONST_PERSISTENT);
        /* (34)  ATM Address  */
-       REGISTER_LONG_CONSTANT("ARES_T_ATMA", ns_t_atma, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_ATMA", T_ATMA, CONST_CS|CONST_PERSISTENT);
        /* (35)  Naming Authority PoinTeR  */
-       REGISTER_LONG_CONSTANT("ARES_T_NAPTR", ns_t_naptr, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_NAPTR", T_NAPTR, CONST_CS|CONST_PERSISTENT);
        /* (36)  Key Exchange  */
-       REGISTER_LONG_CONSTANT("ARES_T_KX", ns_t_kx, CONST_CS|CONST_PERSISTENT);
+       /* REGISTER_LONG_CONSTANT("ARES_T_KX", T_KX, CONST_CS|CONST_PERSISTENT); */
        /* (37)  Certification record  */
-       REGISTER_LONG_CONSTANT("ARES_T_CERT", ns_t_cert, CONST_CS|CONST_PERSISTENT);
+       /* REGISTER_LONG_CONSTANT("ARES_T_CERT", T_CERT, CONST_CS|CONST_PERSISTENT); */
        /* (38)  IPv6 address (deprecates AAAA)  */
-       REGISTER_LONG_CONSTANT("ARES_T_A6", ns_t_a6, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_A6", T_A6, CONST_CS|CONST_PERSISTENT);
        /* (39)  Non-terminal DNAME (for IPv6)  */
-       REGISTER_LONG_CONSTANT("ARES_T_DNAME", ns_t_dname, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_DNAME", T_DNAME, CONST_CS|CONST_PERSISTENT);
        /* (40)  Kitchen sink (experimentatl)  */
-       REGISTER_LONG_CONSTANT("ARES_T_SINK", ns_t_sink, CONST_CS|CONST_PERSISTENT);
+       /* REGISTER_LONG_CONSTANT("ARES_T_SINK", T_SINK, CONST_CS|CONST_PERSISTENT); */
        /* (41)  EDNS0 option (meta-RR)  */
-       REGISTER_LONG_CONSTANT("ARES_T_OPT", ns_t_opt, CONST_CS|CONST_PERSISTENT);
+       /* REGISTER_LONG_CONSTANT("ARES_T_OPT", T_OPT, CONST_CS|CONST_PERSISTENT); */
        /* (250)  Transaction signature.  */
-       REGISTER_LONG_CONSTANT("ARES_T_TSIG", ns_t_tsig, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_TSIG", T_TSIG, CONST_CS|CONST_PERSISTENT);
        /* (251)  Incremental zone transfer.  */
-       REGISTER_LONG_CONSTANT("ARES_T_IXFR", ns_t_ixfr, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_IXFR", T_IXFR, CONST_CS|CONST_PERSISTENT);
        /* (252)  Transfer zone of authority.  */
-       REGISTER_LONG_CONSTANT("ARES_T_AXFR", ns_t_axfr, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_AXFR", T_AXFR, CONST_CS|CONST_PERSISTENT);
        /* (253)  Transfer mailbox records.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MAILB", ns_t_mailb, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MAILB", T_MAILB, CONST_CS|CONST_PERSISTENT);
        /* (254)  Transfer mail agent records.  */
-       REGISTER_LONG_CONSTANT("ARES_T_MAILA", ns_t_maila, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_MAILA", T_MAILA, CONST_CS|CONST_PERSISTENT);
        /* (255)  Wildcard match.  */
-       REGISTER_LONG_CONSTANT("ARES_T_ANY", ns_t_any, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_T_ANY", T_ANY, CONST_CS|CONST_PERSISTENT);
        
        /*
         * ns_c (dnsclass) constants (arpa/nameser.h)
         */
        
        /* (1)  Internet.  */
-       REGISTER_LONG_CONSTANT("ARES_C_IN", ns_c_in, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_C_IN", C_IN, CONST_CS|CONST_PERSISTENT);
        /* (2)  unallocated/unsupported.  */
-       /* REGISTER_LONG_CONSTANT("ARES_C_2", ns_c_2, CONST_CS|CONST_PERSISTENT); */
+       /* REGISTER_LONG_CONSTANT("ARES_C_2", C_2, CONST_CS|CONST_PERSISTENT); */
        /* (3)  MIT Chaos-net.  */
-       REGISTER_LONG_CONSTANT("ARES_C_CHAOS", ns_c_chaos, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_C_CHAOS", C_CHAOS, CONST_CS|CONST_PERSISTENT);
        /* (4)  MIT Hesiod.  */
-       REGISTER_LONG_CONSTANT("ARES_C_HS", ns_c_hs, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_C_HS", C_HS, CONST_CS|CONST_PERSISTENT);
        /* (254)  for prereq. sections in update requests  */
-       /* REGISTER_LONG_CONSTANT("ARES_C_NONE", ns_c_none, CONST_CS|CONST_PERSISTENT); */
+       /* REGISTER_LONG_CONSTANT("ARES_C_NONE", C_NONE, CONST_CS|CONST_PERSISTENT); */
        /* (255)  Wildcard match.  */
-       REGISTER_LONG_CONSTANT("ARES_C_ANY", ns_c_any, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("ARES_C_ANY", C_ANY, CONST_CS|CONST_PERSISTENT);
        
        le_ares = zend_register_list_destructors_ex(php_ares_le_dtor, NULL, PHP_ARES_LE_NAME, module_number);
        le_ares_query = zend_register_list_destructors_ex(php_ares_query_le_dtor, NULL, PHP_ARES_QUERY_LE_NAME, module_number);
@@ -1733,11 +1922,22 @@ static PHP_MINIT_FUNCTION(ares)
 }
 /* }}} */
 
+/* {{{ PHP_MSHUTDOWN_FUNCTION */
+static PHP_MSHUTDOWN_FUNCTION(ares)
+{
+#ifdef HAVE_ARES_LIBRARY_CLEANUP
+       ares_library_cleanup();
+#endif
+       return SUCCESS;
+}
+/* }}} */
+
 /* {{{ PHP_MINFO_FUNCTION */
 static PHP_MINFO_FUNCTION(ares)
 {
        php_info_print_table_start();
        php_info_print_table_header(2, "AsyncResolver support", "enabled");
+       php_info_print_table_row(2, "Version", PHP_ARES_VERSION);
        php_info_print_table_end();
        
        php_info_print_table_start();
@@ -1811,15 +2011,6 @@ zend_function_entry ares_functions[] = {
        PHP_FE(ares_select, ai_ares_select)
        PHP_FE(ares_fds, ai_ares_fds)
        PHP_FE(ares_timeout, NULL)
-       PHP_FE(ares_parse_a_reply, NULL)
-#ifdef HAVE_ARES_PARSE_AAAA_REPLY
-       PHP_FE(ares_parse_aaaa_reply, NULL)
-#endif
-       PHP_FE(ares_parse_ptr_reply, NULL)
-       PHP_FE(ares_expand_name, NULL)
-#ifdef HAVE_ARES_EXPAND_STRING
-       PHP_FE(ares_expand_string, NULL)
-#endif
        {NULL, NULL, NULL}
 };
 /* }}} */
@@ -1830,11 +2021,11 @@ zend_module_entry ares_module_entry = {
        "ares",
        ares_functions,
        PHP_MINIT(ares),
-       NULL,
+       PHP_MSHUTDOWN(ares),
        NULL,
        NULL,
        PHP_MINFO(ares),
-       NO_VERSION_YET,
+       PHP_ARES_VERSION,
        STANDARD_MODULE_PROPERTIES
 };
 /* }}} */