From 5df50c35e1baeee517a0895a2c8a2cc2052b087f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Thu, 3 Dec 2009 21:06:33 +0100
Subject: Added C-Ares.


diff --git a/3rdParty/CAres/SConscript b/3rdParty/CAres/SConscript
new file mode 100644
index 0000000..f422867
--- /dev/null
+++ b/3rdParty/CAres/SConscript
@@ -0,0 +1,49 @@
+Import("env")
+
+myenv = env.Clone()
+myenv.Append(CPPPATH = ["src"])
+if myenv["PLATFORM"] != "win32" :
+  myenv.Append(CPPDEFINES = ["HAVE_CONFIG_H"])
+
+myenv.StaticLibrary("CAres", [
+    "src/ares__close_sockets.c",
+    "src/ares__get_hostent.c",
+    "src/ares__read_line.c",
+    "src/ares__timeval.c",
+    "src/ares_cancel.c",
+    "src/ares_data.c",
+    "src/ares_destroy.c",
+    "src/ares_expand_name.c",
+    "src/ares_expand_string.c",
+    "src/ares_fds.c",
+    "src/ares_free_hostent.c",
+    "src/ares_free_string.c",
+    "src/ares_gethostbyaddr.c",
+    "src/ares_gethostbyname.c",
+    "src/ares_getnameinfo.c",
+    "src/ares_getsock.c",
+    "src/ares_init.c",
+    "src/ares_library_init.c",
+    "src/ares_llist.c",
+    "src/ares_mkquery.c",
+    "src/ares_parse_a_reply.c",
+    "src/ares_parse_aaaa_reply.c",
+    "src/ares_parse_ns_reply.c",
+    "src/ares_parse_ptr_reply.c",
+    "src/ares_parse_srv_reply.c",
+    "src/ares_parse_txt_reply.c",
+    "src/ares_process.c",
+    "src/ares_query.c",
+    "src/ares_search.c",
+    "src/ares_send.c",
+    "src/ares_strcasecmp.c",
+    "src/ares_strdup.c",
+    "src/ares_strerror.c",
+    "src/ares_timeout.c",
+    "src/ares_version.c",
+    "src/ares_writev.c",
+    "src/bitncmp.c",
+    "src/inet_net_pton.c",
+    "src/inet_ntop.c",
+    "src/windows_port.c",
+  ])
diff --git a/3rdParty/CAres/src/ares.h b/3rdParty/CAres/src/ares.h
new file mode 100644
index 0000000..b1c2c22
--- /dev/null
+++ b/3rdParty/CAres/src/ares.h
@@ -0,0 +1,494 @@
+/* $Id: ares.h,v 1.72 2009-11-23 12:03:32 yangtse Exp $ */
+
+/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES__H
+#define ARES__H
+
+#include "ares_version.h"  /* c-ares version defines   */
+#include "ares_build.h"    /* c-ares build definitions */
+#include "ares_rules.h"    /* c-ares rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+   !defined(WIN32) && !defined(__SYMBIAN32__)
+#  define WIN32
+#endif
+
+#include <sys/types.h>
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on system that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
+#include <sys/select.h>
+#endif
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+#include <sys/bsdskt.h>
+#endif
+
+#if defined(WATT32)
+#  include <netinet/in.h>
+#  include <sys/socket.h>
+#  include <tcp.h>
+#elif defined(WIN32)
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include <winsock2.h>
+#  include <ws2tcpip.h>
+#else
+#  include <sys/socket.h>
+#  include <netinet/in.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+** c-ares external API function linkage decorations.
+*/
+
+#if !defined(CARES_STATICLIB) && \
+   (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+   /* __declspec function decoration for Win32 and Symbian DLL's */
+#  if defined(CARES_BUILDING_LIBRARY)
+#    define CARES_EXTERN  __declspec(dllexport)
+#  else
+#    define CARES_EXTERN  __declspec(dllimport)
+#  endif
+#else
+   /* visibility function decoration for other cases */
+#  if !defined(CARES_SYMBOL_HIDING) || \
+     defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+#    define CARES_EXTERN
+#  else
+#    define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
+#  endif
+#endif
+
+
+#define ARES_SUCCESS            0
+
+/* Server error codes (ARES_ENODATA indicates no relevant answer) */
+#define ARES_ENODATA            1
+#define ARES_EFORMERR           2
+#define ARES_ESERVFAIL          3
+#define ARES_ENOTFOUND          4
+#define ARES_ENOTIMP            5
+#define ARES_EREFUSED           6
+
+/* Locally generated error codes */
+#define ARES_EBADQUERY          7
+#define ARES_EBADNAME           8
+#define ARES_EBADFAMILY         9
+#define ARES_EBADRESP           10
+#define ARES_ECONNREFUSED       11
+#define ARES_ETIMEOUT           12
+#define ARES_EOF                13
+#define ARES_EFILE              14
+#define ARES_ENOMEM             15
+#define ARES_EDESTRUCTION       16
+#define ARES_EBADSTR            17
+
+/* ares_getnameinfo error codes */
+#define ARES_EBADFLAGS          18
+
+/* ares_getaddrinfo error codes */
+#define ARES_ENONAME            19
+#define ARES_EBADHINTS          20
+
+/* Uninitialized library error code */
+#define ARES_ENOTINITIALIZED    21          /* introduced in 1.7.0 */
+
+/* ares_library_init error codes */
+#define ARES_ELOADIPHLPAPI           22     /* introduced in 1.7.0 */
+#define ARES_EADDRGETNETWORKPARAMS   23     /* introduced in 1.7.0 */
+
+/* More error codes */
+#define ARES_ECANCELLED         24          /* introduced in 1.7.0 */
+
+/* Flag values */
+#define ARES_FLAG_USEVC         (1 << 0)
+#define ARES_FLAG_PRIMARY       (1 << 1)
+#define ARES_FLAG_IGNTC         (1 << 2)
+#define ARES_FLAG_NORECURSE     (1 << 3)
+#define ARES_FLAG_STAYOPEN      (1 << 4)
+#define ARES_FLAG_NOSEARCH      (1 << 5)
+#define ARES_FLAG_NOALIASES     (1 << 6)
+#define ARES_FLAG_NOCHECKRESP   (1 << 7)
+
+/* Option mask values */
+#define ARES_OPT_FLAGS          (1 << 0)
+#define ARES_OPT_TIMEOUT        (1 << 1)
+#define ARES_OPT_TRIES          (1 << 2)
+#define ARES_OPT_NDOTS          (1 << 3)
+#define ARES_OPT_UDP_PORT       (1 << 4)
+#define ARES_OPT_TCP_PORT       (1 << 5)
+#define ARES_OPT_SERVERS        (1 << 6)
+#define ARES_OPT_DOMAINS        (1 << 7)
+#define ARES_OPT_LOOKUPS        (1 << 8)
+#define ARES_OPT_SOCK_STATE_CB  (1 << 9)
+#define ARES_OPT_SORTLIST       (1 << 10)
+#define ARES_OPT_SOCK_SNDBUF    (1 << 11)
+#define ARES_OPT_SOCK_RCVBUF    (1 << 12)
+#define ARES_OPT_TIMEOUTMS      (1 << 13)
+#define ARES_OPT_ROTATE         (1 << 14)
+
+/* Nameinfo flag values */
+#define ARES_NI_NOFQDN                  (1 << 0)
+#define ARES_NI_NUMERICHOST             (1 << 1)
+#define ARES_NI_NAMEREQD                (1 << 2)
+#define ARES_NI_NUMERICSERV             (1 << 3)
+#define ARES_NI_DGRAM                   (1 << 4)
+#define ARES_NI_TCP                     0
+#define ARES_NI_UDP                     ARES_NI_DGRAM
+#define ARES_NI_SCTP                    (1 << 5)
+#define ARES_NI_DCCP                    (1 << 6)
+#define ARES_NI_NUMERICSCOPE            (1 << 7)
+#define ARES_NI_LOOKUPHOST              (1 << 8)
+#define ARES_NI_LOOKUPSERVICE           (1 << 9)
+/* Reserved for future use */
+#define ARES_NI_IDN                     (1 << 10)
+#define ARES_NI_IDN_ALLOW_UNASSIGNED    (1 << 11)
+#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+
+/* Addrinfo flag values */
+#define ARES_AI_CANONNAME               (1 << 0)
+#define ARES_AI_NUMERICHOST             (1 << 1)
+#define ARES_AI_PASSIVE                 (1 << 2)
+#define ARES_AI_NUMERICSERV             (1 << 3)
+#define ARES_AI_V4MAPPED                (1 << 4)
+#define ARES_AI_ALL                     (1 << 5)
+#define ARES_AI_ADDRCONFIG              (1 << 6)
+/* Reserved for future use */
+#define ARES_AI_IDN                     (1 << 10)
+#define ARES_AI_IDN_ALLOW_UNASSIGNED    (1 << 11)
+#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+#define ARES_AI_CANONIDN                (1 << 13)
+
+#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
+                      ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
+                      ARES_AI_ADDRCONFIG)
+#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
+                                  many sockets */
+#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
+#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
+                                         ARES_GETSOCK_MAXNUM)))
+
+/* c-ares library initialization flag values */
+#define ARES_LIB_INIT_NONE   (0)
+#define ARES_LIB_INIT_WIN32  (1 << 0)
+#define ARES_LIB_INIT_ALL    (ARES_LIB_INIT_WIN32)
+
+
+/*
+ * Typedef our socket type
+ */
+
+#ifndef ares_socket_typedef
+#ifdef WIN32
+typedef SOCKET ares_socket_t;
+#define ARES_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int ares_socket_t;
+#define ARES_SOCKET_BAD -1
+#endif
+#define ares_socket_typedef
+#endif /* ares_socket_typedef */
+
+typedef void (*ares_sock_state_cb)(void *data,
+                                   ares_socket_t socket_fd,
+                                   int readable,
+                                   int writable);
+
+struct apattern;
+
+/* NOTE about the ares_options struct to users and developers.
+
+   This struct will remain looking like this. It will not be extended nor
+   shrunk in future releases, but all new options will be set by ares_set_*()
+   options instead of with the ares_init_options() function.
+
+   Eventually (in a galaxy far far away), all options will be settable by
+   ares_set_*() options and the ares_init_options() function will become
+   deprecated.
+
+   When new options are added to c-ares, they are not added to this
+   struct. And they are not "saved" with the ares_save_options() function but
+   instead we encourage the use of the ares_dup() function. Needless to say,
+   if you add config options to c-ares you need to make sure ares_dup()
+   duplicates this new option.
+
+ */
+struct ares_options {
+  int flags;
+  int timeout; /* in seconds or milliseconds, depending on options */
+  int tries;
+  int ndots;
+  unsigned short udp_port;
+  unsigned short tcp_port;
+  int socket_send_buffer_size;
+  int socket_receive_buffer_size;
+  struct in_addr *servers;
+  int nservers;
+  char **domains;
+  int ndomains;
+  char *lookups;
+  ares_sock_state_cb sock_state_cb;
+  void *sock_state_cb_data;
+  struct apattern *sortlist;
+  int nsort;
+};
+
+struct hostent;
+struct timeval;
+struct sockaddr;
+struct ares_channeldata;
+
+typedef struct ares_channeldata *ares_channel;
+
+typedef void (*ares_callback)(void *arg,
+                              int status,
+                              int timeouts,
+                              unsigned char *abuf,
+                              int alen);
+
+typedef void (*ares_host_callback)(void *arg,
+                                   int status,
+                                   int timeouts,
+                                   struct hostent *hostent);
+
+typedef void (*ares_nameinfo_callback)(void *arg,
+                                       int status,
+                                       int timeouts,
+                                       char *node,
+                                       char *service);
+
+typedef int  (*ares_sock_create_callback)(ares_socket_t socket_fd,
+                                          int type,
+                                          void *data);
+
+CARES_EXTERN int ares_library_init(int flags);
+
+CARES_EXTERN void ares_library_cleanup(void);
+
+CARES_EXTERN const char *ares_version(int *version);
+
+CARES_EXTERN int ares_init(ares_channel *channelptr);
+
+CARES_EXTERN int ares_init_options(ares_channel *channelptr,
+                                   struct ares_options *options,
+                                   int optmask);
+
+CARES_EXTERN int ares_save_options(ares_channel channel,
+                                   struct ares_options *options,
+                                   int *optmask);
+
+CARES_EXTERN void ares_destroy_options(struct ares_options *options);
+
+CARES_EXTERN int ares_dup(ares_channel *dest,
+                          ares_channel src);
+
+CARES_EXTERN void ares_destroy(ares_channel channel);
+
+CARES_EXTERN void ares_cancel(ares_channel channel);
+
+CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
+                                           ares_sock_create_callback callback,
+                                           void *user_data);
+
+CARES_EXTERN void ares_send(ares_channel channel,
+                            const unsigned char *qbuf,
+                            int qlen,
+                            ares_callback callback,
+                            void *arg);
+
+CARES_EXTERN void ares_query(ares_channel channel,
+                             const char *name,
+                             int dnsclass,
+                             int type,
+                             ares_callback callback,
+                             void *arg);
+
+CARES_EXTERN void ares_search(ares_channel channel,
+                              const char *name,
+                              int dnsclass,
+                              int type,
+                              ares_callback callback,
+                              void *arg);
+
+CARES_EXTERN void ares_gethostbyname(ares_channel channel,
+                                     const char *name,
+                                     int family,
+                                     ares_host_callback callback,
+                                     void *arg);
+
+CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
+                                         const char *name,
+                                         int family,
+                                         struct hostent **host);
+
+CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
+                                     const void *addr,
+                                     int addrlen,
+                                     int family,
+                                     ares_host_callback callback,
+                                     void *arg);
+
+CARES_EXTERN void ares_getnameinfo(ares_channel channel,
+                                   const struct sockaddr *sa,
+                                   ares_socklen_t salen,
+                                   int flags,
+                                   ares_nameinfo_callback callback,
+                                   void *arg);
+
+CARES_EXTERN int ares_fds(ares_channel channel,
+                          fd_set *read_fds,
+                          fd_set *write_fds);
+
+CARES_EXTERN int ares_getsock(ares_channel channel,
+                              int *socks,
+                              int numsocks);
+
+CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
+                                          struct timeval *maxtv,
+                                          struct timeval *tv);
+
+CARES_EXTERN void ares_process(ares_channel channel,
+                               fd_set *read_fds,
+                               fd_set *write_fds);
+
+CARES_EXTERN void ares_process_fd(ares_channel channel,
+                                  ares_socket_t read_fd,
+                                  ares_socket_t write_fd);
+
+CARES_EXTERN int ares_mkquery(const char *name,
+                              int dnsclass,
+                              int type,
+                              unsigned short id,
+                              int rd,
+                              unsigned char **buf,
+                              int *buflen);
+
+CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
+                                  const unsigned char *abuf,
+                                  int alen,
+                                  char **s,
+                                  long *enclen);
+
+CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
+                                    const unsigned char *abuf,
+                                    int alen,
+                                    unsigned char **s,
+                                    long *enclen);
+
+/*
+ * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr
+ * struct below when ares itself was built, but many apps would use this
+ * private version since the header checked a HAVE_* define for it. Starting
+ * with 1.7.0 we always declare and use our own to stop relying on the
+ * system's one.
+ */
+struct ares_in6_addr {
+  union {
+    unsigned char _S6_u8[16];
+  } _S6_un;
+};
+
+struct ares_addrttl {
+  struct in_addr ipaddr;
+  int            ttl;
+};
+
+struct ares_addr6ttl {
+  struct ares_in6_addr ip6addr;
+  int             ttl;
+};
+
+struct ares_srv_reply {
+  struct ares_srv_reply  *next;
+  char                   *host;
+  unsigned short          priority;
+  unsigned short          weight;
+  unsigned short          port;
+};
+
+struct ares_txt_reply {
+  struct ares_txt_reply  *next;
+  unsigned char          *txt;
+  size_t                  length;  /* length excludes null termination */
+};
+
+/*
+** Parse the buffer, starting at *abuf and of length alen bytes, previously
+** obtained from an ares_search call.  Put the results in *host, if nonnull.
+** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
+** their TTLs in that array, and set *naddrttls to the number of addresses
+** so written.
+*/
+
+CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
+                                    int alen,
+                                    struct hostent **host,
+                                    struct ares_addrttl *addrttls,
+                                    int *naddrttls);
+
+CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
+                                       int alen,
+                                       struct hostent **host,
+                                       struct ares_addr6ttl *addrttls,
+                                       int *naddrttls);
+
+CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
+                                      int alen,
+                                      const void *addr,
+                                      int addrlen,
+                                      int family,
+                                      struct hostent **host);
+
+CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
+                                     int alen,
+                                     struct hostent **host);
+
+CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
+                                      int alen,
+                                      struct ares_srv_reply** srv_out);
+
+CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
+                                      int alen,
+                                      struct ares_txt_reply** txt_out);
+
+CARES_EXTERN void ares_free_string(void *str);
+
+CARES_EXTERN void ares_free_hostent(struct hostent *host);
+
+CARES_EXTERN void ares_free_data(void *dataptr);
+
+CARES_EXTERN const char *ares_strerror(int code);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* ARES__H */
diff --git a/3rdParty/CAres/src/ares__close_sockets.c b/3rdParty/CAres/src/ares__close_sockets.c
new file mode 100644
index 0000000..ef8910d
--- /dev/null
+++ b/3rdParty/CAres/src/ares__close_sockets.c
@@ -0,0 +1,67 @@
+/* $Id: ares__close_sockets.c,v 1.10 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+void ares__close_sockets(ares_channel channel, struct server_state *server)
+{
+  struct send_request *sendreq;
+
+  /* Free all pending output buffers. */
+  while (server->qhead)
+    {
+      /* Advance server->qhead; pull out query as we go. */
+      sendreq = server->qhead;
+      server->qhead = sendreq->next;
+      if (sendreq->data_storage != NULL)
+        free(sendreq->data_storage);
+      free(sendreq);
+    }
+  server->qtail = NULL;
+
+  /* Reset any existing input buffer. */
+  if (server->tcp_buffer)
+    free(server->tcp_buffer);
+  server->tcp_buffer = NULL;
+  server->tcp_lenbuf_pos = 0;
+
+  /* Reset brokenness */
+  server->is_broken = 0;
+
+  /* Close the TCP and UDP sockets. */
+  if (server->tcp_socket != ARES_SOCKET_BAD)
+    {
+      SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
+      sclose(server->tcp_socket);
+      server->tcp_socket = ARES_SOCKET_BAD;
+      server->tcp_connection_generation = ++channel->tcp_connection_generation;
+    }
+  if (server->udp_socket != ARES_SOCKET_BAD)
+    {
+      SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
+      sclose(server->udp_socket);
+      server->udp_socket = ARES_SOCKET_BAD;
+    }
+}
diff --git a/3rdParty/CAres/src/ares__get_hostent.c b/3rdParty/CAres/src/ares__get_hostent.c
new file mode 100644
index 0000000..335f763
--- /dev/null
+++ b/3rdParty/CAres/src/ares__get_hostent.c
@@ -0,0 +1,264 @@
+/* $Id: ares__get_hostent.c,v 1.24 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "ares_private.h"
+
+int ares__get_hostent(FILE *fp, int family, struct hostent **host)
+{
+  char *line = NULL, *p, *q, **alias;
+  char *txtaddr, *txthost, *txtalias;
+  int status;
+  size_t addrlen, linesize, naliases;
+  struct ares_addr addr;
+  struct hostent *hostent = NULL;
+
+  *host = NULL; /* Assume failure */
+
+  /* Validate family */
+  switch (family) {
+    case AF_INET:
+    case AF_INET6:
+    case AF_UNSPEC:
+      break;
+    default:
+      return ARES_EBADFAMILY;
+  }
+
+  while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+    {
+
+      /* Trim line comment. */
+      p = line;
+      while (*p && (*p != '#'))
+        p++;
+      *p = '\0';
+
+      /* Trim trailing whitespace. */
+      q = p - 1;
+      while ((q >= line) && ISSPACE(*q))
+        q--;
+      *++q = '\0';
+
+      /* Skip leading whitespace. */
+      p = line;
+      while (*p && ISSPACE(*p))
+        p++;
+      if (!*p)
+        /* Ignore line if empty. */
+        continue;
+
+      /* Pointer to start of IPv4 or IPv6 address part. */
+      txtaddr = p;
+
+      /* Advance past address part. */
+      while (*p && !ISSPACE(*p))
+        p++;
+      if (!*p)
+        /* Ignore line if reached end of line. */
+        continue;
+
+      /* Null terminate address part. */
+      *p = '\0';
+
+      /* Advance to host name */
+      p++;
+      while (*p && ISSPACE(*p))
+        p++;
+      if (!*p)
+        /* Ignore line if reached end of line. */
+        continue;
+
+      /* Pointer to start of host name. */
+      txthost = p;
+
+      /* Advance past host name. */
+      while (*p && !ISSPACE(*p))
+        p++;
+
+      /* Pointer to start of first alias. */
+      txtalias = NULL;
+      if (*p)
+        {
+          q = p + 1;
+          while (*q && ISSPACE(*q))
+            q++;
+          if (*q)
+            txtalias = q;
+        }
+
+      /* Null terminate host name. */
+      *p = '\0';
+
+      /* find out number of aliases. */
+      naliases = 0;
+      if (txtalias)
+        {
+          p = txtalias;
+          while (*p)
+            {
+              while (*p && !ISSPACE(*p))
+                p++;
+              while (*p && ISSPACE(*p))
+                p++;
+              naliases++;
+            }
+        }
+
+      /* Convert address string to network address for the requested family. */
+      addrlen = 0;
+      addr.family = AF_UNSPEC;
+      addr.addrV4.s_addr = INADDR_NONE;
+      if ((family == AF_INET) || (family == AF_UNSPEC))
+        {
+          addr.addrV4.s_addr = inet_addr(txtaddr);
+          if (addr.addrV4.s_addr != INADDR_NONE)
+            {
+              /* Actual network address family and length. */
+              addr.family = AF_INET;
+              addrlen = sizeof(struct in_addr);
+            }
+        }
+      if ((family == AF_INET6) || ((family == AF_UNSPEC) && (!addrlen)))
+        {
+          if (ares_inet_pton(AF_INET6, txtaddr, &addr.addrV6) > 0)
+            {
+              /* Actual network address family and length. */
+              addr.family = AF_INET6;
+              addrlen = sizeof(struct in6_addr);
+            }
+        }
+      if (!addrlen)
+        /* Ignore line if invalid address string for the requested family. */
+        continue;
+
+      /*
+      ** Actual address family possible values are AF_INET and AF_INET6 only.
+      */
+
+      /* Allocate memory for the hostent structure. */
+      hostent = malloc(sizeof(struct hostent));
+      if (!hostent)
+        break;
+
+      /* Initialize fields for out of memory condition. */
+      hostent->h_aliases = NULL;
+      hostent->h_addr_list = NULL;
+
+      /* Copy official host name. */
+      hostent->h_name = strdup(txthost);
+      if (!hostent->h_name)
+        break;
+
+      /* Copy network address. */
+      hostent->h_addr_list = malloc(2 * sizeof(char *));
+      if (!hostent->h_addr_list)
+        break;
+      hostent->h_addr_list[1] = NULL;
+      hostent->h_addr_list[0] = malloc(addrlen);
+      if (!hostent->h_addr_list[0])
+        break;
+      if (addr.family == AF_INET)
+        memcpy(hostent->h_addr_list[0], &addr.addrV4, sizeof(struct in_addr));
+      else
+        memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(struct in6_addr));
+
+      /* Copy aliases. */
+      hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
+      if (!hostent->h_aliases)
+        break;
+      alias = hostent->h_aliases;
+      while (naliases)
+        *(alias + naliases--) = NULL;
+      *alias = NULL;
+      while (txtalias)
+        {
+          p = txtalias;
+          while (*p && !ISSPACE(*p))
+            p++;
+          q = p;
+          while (*q && ISSPACE(*q))
+            q++;
+          *p = '\0';
+          if ((*alias = strdup(txtalias)) == NULL)
+            break;
+          alias++;
+          txtalias = *q ? q : NULL;
+        }
+      if (txtalias)
+        /* Alias memory allocation failure. */
+        break;
+
+      /* Copy actual network address family and length. */
+      hostent->h_addrtype = addr.family;
+      hostent->h_length = (int)addrlen;
+
+      /* Free line buffer. */
+      free(line);
+
+      /* Return hostent successfully */
+      *host = hostent;
+      return ARES_SUCCESS;
+
+    }
+
+  /* If allocated, free line buffer. */
+  if (line)
+    free(line);
+
+  if (status == ARES_SUCCESS)
+    {
+      /* Memory allocation failure; clean up. */
+      if (hostent)
+        {
+          if (hostent->h_name)
+            free((char *) hostent->h_name);
+          if (hostent->h_aliases)
+            {
+              for (alias = hostent->h_aliases; *alias; alias++)
+                free(*alias);
+              free(hostent->h_aliases);
+            }
+          if (hostent->h_addr_list)
+            {
+              if (hostent->h_addr_list[0])
+                free(hostent->h_addr_list[0]);
+              free(hostent->h_addr_list);
+            }
+          free(hostent);
+        }
+      return ARES_ENOMEM;
+    }
+
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares__read_line.c b/3rdParty/CAres/src/ares__read_line.c
new file mode 100644
index 0000000..270e0e3
--- /dev/null
+++ b/3rdParty/CAres/src/ares__read_line.c
@@ -0,0 +1,67 @@
+/* $Id: ares__read_line.c,v 1.14 2009-11-10 18:41:03 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_private.h"
+
+/* This is an internal function.  Its contract is to read a line from
+ * a file into a dynamically allocated buffer, zeroing the trailing
+ * newline if there is one.  The calling routine may call
+ * ares__read_line multiple times with the same buf and bufsize
+ * pointers; *buf will be reallocated and *bufsize adjusted as
+ * appropriate.  The initial value of *buf should be NULL.  After the
+ * calling routine is done reading lines, it should free *buf.
+ */
+int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
+{
+  char *newbuf;
+  size_t offset = 0;
+  size_t len;
+
+  if (*buf == NULL)
+    {
+      *buf = malloc(128);
+      if (!*buf)
+        return ARES_ENOMEM;
+      *bufsize = 128;
+    }
+
+  for (;;)
+    {
+      if (!fgets(*buf + offset, (int)(*bufsize - offset), fp))
+        return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF;
+      len = offset + strlen(*buf + offset);
+      if ((*buf)[len - 1] == '\n')
+        {
+          (*buf)[len - 1] = 0;
+          break;
+        }
+      offset = len;
+
+      /* Allocate more space. */
+      newbuf = realloc(*buf, *bufsize * 2);
+      if (!newbuf)
+        return ARES_ENOMEM;
+      *buf = newbuf;
+      *bufsize *= 2;
+    }
+  return ARES_SUCCESS;
+}
diff --git a/3rdParty/CAres/src/ares__timeval.c b/3rdParty/CAres/src/ares__timeval.c
new file mode 100644
index 0000000..2957350
--- /dev/null
+++ b/3rdParty/CAres/src/ares__timeval.c
@@ -0,0 +1,112 @@
+/* $Id: ares__timeval.c,v 1.6 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright (C) 2008 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares.h"
+#include "ares_private.h"
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct timeval ares__tvnow(void)
+{
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct timeval now;
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct timeval ares__tvnow(void)
+{
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
+  return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval ares__tvnow(void)
+{
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
+  struct timeval now;
+  (void)gettimeofday(&now, NULL);
+  return now;
+}
+
+#else
+
+struct timeval ares__tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
+#if 0 /* Not used */
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long ares__tvdiff(struct timeval newer, struct timeval older)
+{
+  return (newer.tv_sec-older.tv_sec)*1000+
+    (newer.tv_usec-older.tv_usec)/1000;
+}
+#endif
+
diff --git a/3rdParty/CAres/src/ares_build.h b/3rdParty/CAres/src/ares_build.h
new file mode 100644
index 0000000..bbbef1b
--- /dev/null
+++ b/3rdParty/CAres/src/ares_build.h
@@ -0,0 +1,253 @@
+#ifndef __CARES_BUILD_H
+#define __CARES_BUILD_H
+
+/* $Id: ares_build.h.dist,v 1.9 2009-05-12 01:57:53 yangtse Exp $ */
+
+/* Copyright (C) 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/*               NOTES FOR CONFIGURE CAPABLE SYSTEMS                */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * See file ares_build.h.in, run configure, and forget that this file
+ * exists it is only used for non-configure systems.
+ * But you can keep reading if you want ;-)
+ *
+ */
+
+/* ================================================================ */
+/*                 NOTES FOR NON-CONFIGURE SYSTEMS                  */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * c-ares library user nor by the c-ares library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the c-ares development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/
+ *
+ * Try to keep one section per platform, compiler and architecture,
+ * otherwise, if an existing section is reused for a different one and
+ * later on the original is adjusted, probably the piggybacking one can
+ * be adversely changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures
+ * use only compiler built in predefined preprocessor symbols.
+ *
+ * This header file shall only export symbols which are 'cares' or 'CARES'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file ares_build.h.dist or ares_build.h,
+ * this is due to the following reason: file ares_build.h.dist is renamed
+ * to ares_build.h when the c-ares source code distribution archive file is
+ * created.
+ *
+ * File ares_build.h.dist is not included in the distribution archive.
+ * File ares_build.h is not present in the CVS tree.
+ *
+ * The distributed ares_build.h file is only intended to be used on systems
+ * which can not run the also distributed configure script.
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed ares_build.h file with one that is suitable
+ * and specific to the library being configured and built, which is generated
+ * from the ares_build.h.in template file.
+ *
+ * If you check out from CVS on a non-configure platform, you must run the
+ * appropriate buildconf* script to set up ares_build.h and other local files.
+ *
+ */
+
+/* ================================================================ */
+/*  DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE  */
+/* ================================================================ */
+
+#ifdef CARES_SIZEOF_LONG
+#  error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CARES_TYPEOF_ARES_SOCKLEN_T
+#  error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CARES_SIZEOF_ARES_SOCKLEN_T
+#  error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+   Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+/* ================================================================ */
+/*    EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY    */
+/* ================================================================ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__SALFORDC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__BORLANDC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__TURBOC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__WATCOMC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__POCC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__LCC__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__SYMBIAN32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T unsigned int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__MWERKS__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(_WIN32_WCE)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__MINGW32__)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__VMS)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T unsigned int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CARES_SIZEOF_LONG           4
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CARES_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CARES_SIZEOF_LONG           8
+#    endif
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CARES_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CARES_SIZEOF_LONG           8
+#    endif
+#    define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#    define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#    define CARES_PULL_SYS_TYPES_H      1
+#    define CARES_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CARES_SIZEOF_LONG           8
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  define CARES_SIZEOF_LONG           4
+#  define CARES_TYPEOF_ARES_SOCKLEN_T int
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+#  if defined(__i386__) || defined(__ppc__)
+#    define CARES_SIZEOF_LONG           4
+#  elif defined(__x86_64__) || defined(__ppc64__)
+#    define CARES_SIZEOF_LONG           8
+#  endif
+#  define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+#  define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#  define CARES_PULL_SYS_TYPES_H      1
+#  define CARES_PULL_SYS_SOCKET_H     1
+
+#else
+#  error "Unknown non-configure build target!"
+   Error Compilation_aborted_Unknown_non_configure_build_target
+#endif
+
+/* CARES_PULL_SYS_TYPES_H is defined above when inclusion of header file  */
+/* sys/types.h is required here to properly make type definitions below.  */
+#ifdef CARES_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CARES_PULL_SYS_SOCKET_H is defined above when inclusion of header file  */
+/* sys/socket.h is required here to properly make type definitions below.  */
+#ifdef CARES_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* Data type definition of ares_socklen_t. */
+
+#ifdef CARES_TYPEOF_ARES_SOCKLEN_T
+  typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
+#endif
+
+#endif /* __CARES_BUILD_H */
diff --git a/3rdParty/CAres/src/ares_cancel.c b/3rdParty/CAres/src/ares_cancel.c
new file mode 100644
index 0000000..9478085
--- /dev/null
+++ b/3rdParty/CAres/src/ares_cancel.c
@@ -0,0 +1,64 @@
+/* $Id: ares_cancel.c,v 1.12 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright (C) 2004 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <assert.h>
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h"
+
+/*
+ * ares_cancel() cancels all ongoing requests/resolves that might be going on
+ * on the given channel. It does NOT kill the channel, use ares_destroy() for
+ * that.
+ */
+void ares_cancel(ares_channel channel)
+{
+  struct query *query;
+  struct list_node* list_head;
+  struct list_node* list_node;
+  int i;
+
+  list_head = &(channel->all_queries);
+  for (list_node = list_head->next; list_node != list_head; )
+  {
+    query = list_node->data;
+    list_node = list_node->next;  /* since we're deleting the query */
+    query->callback(query->arg, ARES_ECANCELLED, 0, NULL, 0);
+    ares__free_query(query);
+  }
+#ifndef NDEBUG
+  /* Freeing the query should remove it from all the lists in which it sits,
+   * so all query lists should be empty now.
+   */
+  assert(ares__is_list_empty(&(channel->all_queries)));
+  for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
+    {
+      assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
+    }
+  for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
+    {
+      assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
+    }
+#endif
+  if (!(channel->flags & ARES_FLAG_STAYOPEN))
+  {
+    if (channel->servers)
+    {
+      for (i = 0; i < channel->nservers; i++)
+        ares__close_sockets(channel, &channel->servers[i]);
+    }
+  }
+}
diff --git a/3rdParty/CAres/src/ares_config.h b/3rdParty/CAres/src/ares_config.h
new file mode 100644
index 0000000..2561090
--- /dev/null
+++ b/3rdParty/CAres/src/ares_config.h
@@ -0,0 +1,513 @@
+/* ares_config.h.  Generated from ares_config.h.in by configure.  */
+/* ares_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define this if ares is built for a big endian system */
+/* #undef ARES_BIG_ENDIAN */
+
+/* when building as static part of libcurl */
+/* #undef BUILDING_LIBCURL */
+
+/* when building c-ares library */
+/* #undef CARES_BUILDING_LIBRARY */
+
+/* when not building a shared library */
+/* #undef CARES_STATICLIB */
+
+/* Define to 1 to enable hiding of library internal symbols. */
+#define CARES_SYMBOL_HIDING 1
+
+/* Definition to make a library symbol externally visible. */
+#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default")))
+
+/* if a /etc/inet dir is being used */
+/* #undef ETC_INET */
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 unsigned int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#define HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#define HAVE_GETADDRINFO_THREADSAFE 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+#define HAVE_GETSERVBYPORT_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME 1
+
+/* Define to 1 if you have the `inet_net_pton' function. */
+/* #undef HAVE_INET_NET_PTON */
+
+/* Define to 1 if inet_net_pton supports IPv6. */
+/* #undef HAVE_INET_NET_PTON_IPV6 */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#define HAVE_STROPTS_H 1
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR 1
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you are building a native Windows target. */
+/* #undef NATIVE_WINDOWS */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* cpu-machine-OS */
+#define OS "i686-pc-linux-gnu"
+
+/* Name of package */
+#define PACKAGE "c-ares"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares 1.7.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.7.0"
+
+/* a suitable file/device to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `struct in6_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN6_ADDR 16
+
+/* The size of `struct in_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN_ADDR 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* Version number of package */
+#define VERSION "1.7.0"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#define _FILE_OFFSET_BITS 64
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
diff --git a/3rdParty/CAres/src/ares_data.c b/3rdParty/CAres/src/ares_data.c
new file mode 100644
index 0000000..1ad66a6
--- /dev/null
+++ b/3rdParty/CAres/src/ares_data.c
@@ -0,0 +1,143 @@
+/* $Id: ares_data.c,v 1.2 2009-11-20 09:06:33 yangtse Exp $ */
+
+/* Copyright (C) 2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+#include "ares_setup.h"
+
+#include <stddef.h>
+
+#include "ares.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+
+/*
+** ares_free_data() - c-ares external API function.
+**
+** This function must be used by the application to free data memory that
+** has been internally allocated by some c-ares function and for which a
+** pointer has already been returned to the calling application. The list
+** of c-ares functions returning pointers that must be free'ed using this
+** function is:
+**
+**   ares_parse_srv_reply()
+**   ares_parse_txt_reply()
+*/
+
+void ares_free_data(void *dataptr)
+{
+  struct ares_data *ptr;
+
+  if (!dataptr)
+    return;
+
+  ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
+
+  if (ptr->mark != ARES_DATATYPE_MARK)
+    return;
+
+  switch (ptr->type)
+    {
+      case ARES_DATATYPE_SRV_REPLY:
+
+        if (ptr->data.srv_reply.next)
+          ares_free_data(ptr->data.srv_reply.next);
+        if (ptr->data.srv_reply.host)
+          free(ptr->data.srv_reply.host);
+        break;
+
+      case ARES_DATATYPE_TXT_REPLY:
+
+        if (ptr->data.txt_reply.next)
+          ares_free_data(ptr->data.txt_reply.next);
+        if (ptr->data.txt_reply.txt)
+          free(ptr->data.txt_reply.txt);
+        break;
+
+      default:
+        return;
+    }
+
+  free(ptr);
+}
+
+
+/*
+** ares_malloc_data() - c-ares internal helper function.
+**
+** This function allocates memory for a c-ares private ares_data struct
+** for the specified ares_datatype, initializes c-ares private fields
+** and zero initializes those which later might be used from the public
+** API. It returns an interior pointer which can be passed by c-ares
+** functions to the calling application, and that must be free'ed using
+** c-ares external API function ares_free_data().
+*/
+
+void *ares_malloc_data(ares_datatype type)
+{
+  struct ares_data *ptr;
+
+  ptr = malloc(sizeof(struct ares_data));
+  if (!ptr)
+    return NULL;
+
+  switch (type)
+    {
+      case ARES_DATATYPE_SRV_REPLY:
+        ptr->data.srv_reply.next = NULL;
+        ptr->data.srv_reply.host = NULL;
+        ptr->data.srv_reply.priority = 0;
+        ptr->data.srv_reply.weight = 0;
+        ptr->data.srv_reply.port = 0;
+        break;
+
+      case ARES_DATATYPE_TXT_REPLY:
+        ptr->data.txt_reply.next = NULL;
+        ptr->data.txt_reply.txt = NULL;
+        ptr->data.txt_reply.length  = 0;
+        break;
+
+      default:
+        free(ptr);
+        return NULL;
+    }
+
+  ptr->mark = ARES_DATATYPE_MARK;
+  ptr->type = type;
+
+  return &ptr->data;
+}
+
+
+/*
+** ares_get_datatype() - c-ares internal helper function.
+**
+** This function returns the ares_datatype of the data stored in a
+** private ares_data struct when given the public API pointer.
+*/
+
+ares_datatype ares_get_datatype(void * dataptr)
+{
+  struct ares_data *ptr;
+
+  ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
+
+  if (ptr->mark == ARES_DATATYPE_MARK)
+    return ptr->type;
+
+  return ARES_DATATYPE_UNKNOWN;
+}
diff --git a/3rdParty/CAres/src/ares_data.h b/3rdParty/CAres/src/ares_data.h
new file mode 100644
index 0000000..18794e3
--- /dev/null
+++ b/3rdParty/CAres/src/ares_data.h
@@ -0,0 +1,62 @@
+/* $Id: ares_data.h,v 1.2 2009-11-23 12:03:33 yangtse Exp $ */
+
+/* Copyright (C) 2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+typedef enum {
+  ARES_DATATYPE_UNKNOWN = 1,  /* unknown data type     - introduced in 1.7.0 */
+  ARES_DATATYPE_SRV_REPLY,    /* struct ares_srv_reply - introduced in 1.7.0 */
+  ARES_DATATYPE_TXT_REPLY,    /* struct ares_txt_reply - introduced in 1.7.0 */
+#if 0
+  ARES_DATATYPE_ADDR6TTL,     /* struct ares_addrttl   */
+  ARES_DATATYPE_ADDRTTL,      /* struct ares_addr6ttl  */
+  ARES_DATATYPE_HOSTENT,      /* struct hostent        */
+  ARES_DATATYPE_OPTIONS,      /* struct ares_options   */
+#endif
+  ARES_DATATYPE_LAST          /* not used              - introduced in 1.7.0 */
+} ares_datatype;
+
+#define ARES_DATATYPE_MARK 0xbead
+
+/*
+ * ares_data struct definition is internal to c-ares and shall not
+ * be exposed by the public API in order to allow future changes
+ * and extensions to it without breaking ABI.  This will be used
+ * internally by c-ares as the container of multiple types of data
+ * dynamically allocated for which a reference will be returned
+ * to the calling application.
+ *
+ * c-ares API functions returning a pointer to c-ares internally
+ * allocated data will actually be returning an interior pointer
+ * into this ares_data struct.
+ *
+ * All this is 'invisible' to the calling application, the only
+ * requirement is that this kind of data must be free'ed by the
+ * calling application using ares_free_data() with the pointer
+ * it has received from a previous c-ares function call.
+ */
+
+struct ares_data {
+  ares_datatype type;  /* Actual data type identifier. */
+  unsigned int  mark;  /* Private ares_data signature. */
+  union {
+    struct ares_txt_reply txt_reply;
+    struct ares_srv_reply srv_reply;
+  } data;
+};
+
+void *ares_malloc_data(ares_datatype type);
+
+ares_datatype ares_get_datatype(void * dataptr);
diff --git a/3rdParty/CAres/src/ares_destroy.c b/3rdParty/CAres/src/ares_destroy.c
new file mode 100644
index 0000000..0044a71
--- /dev/null
+++ b/3rdParty/CAres/src/ares_destroy.c
@@ -0,0 +1,93 @@
+/* $Id: ares_destroy.c,v 1.14 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <assert.h>
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h"
+
+void ares_destroy_options(struct ares_options *options)
+{
+  int i;
+
+  free(options->servers);
+  for (i = 0; i < options->ndomains; i++)
+    free(options->domains[i]);
+  free(options->domains);
+  if(options->sortlist)
+    free(options->sortlist);
+  free(options->lookups);
+}
+
+void ares_destroy(ares_channel channel)
+{
+  int i;
+  struct query *query;
+  struct list_node* list_head;
+  struct list_node* list_node;
+  
+  if (!channel)
+    return;
+
+  list_head = &(channel->all_queries);
+  for (list_node = list_head->next; list_node != list_head; )
+    {
+      query = list_node->data;
+      list_node = list_node->next;  /* since we're deleting the query */
+      query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0);
+      ares__free_query(query);
+    }
+#ifndef NDEBUG
+  /* Freeing the query should remove it from all the lists in which it sits,
+   * so all query lists should be empty now.
+   */
+  assert(ares__is_list_empty(&(channel->all_queries)));
+  for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
+    {
+      assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
+    }
+  for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
+    {
+      assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
+    }
+#endif
+
+  if (channel->servers) {
+    for (i = 0; i < channel->nservers; i++)
+      {
+        struct server_state *server = &channel->servers[i];
+        ares__close_sockets(channel, server);
+        assert(ares__is_list_empty(&(server->queries_to_server)));
+      }
+    free(channel->servers);
+  }
+
+  if (channel->domains) {
+    for (i = 0; i < channel->ndomains; i++)
+      free(channel->domains[i]);
+    free(channel->domains);
+  }
+
+  if(channel->sortlist)
+    free(channel->sortlist);
+
+  if (channel->lookups)
+    free(channel->lookups);
+
+  free(channel);
+}
diff --git a/3rdParty/CAres/src/ares_dns.h b/3rdParty/CAres/src/ares_dns.h
new file mode 100644
index 0000000..c0a9dda
--- /dev/null
+++ b/3rdParty/CAres/src/ares_dns.h
@@ -0,0 +1,91 @@
+/* $Id: ares_dns.h,v 1.8 2007-02-16 14:22:08 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES__DNS_H
+#define ARES__DNS_H
+
+#define DNS__16BIT(p)                   (((p)[0] << 8) | (p)[1])
+#define DNS__32BIT(p)                   (((p)[0] << 24) | ((p)[1] << 16) | \
+                                         ((p)[2] << 8) | (p)[3])
+
+#define DNS__SET16BIT(p, v)  (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \
+                              ((p)[1] = (unsigned char)((v) & 0xff)))
+#define DNS__SET32BIT(p, v)  (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \
+                              ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \
+                              ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \
+                              ((p)[3] = (unsigned char)((v) & 0xff)))
+
+#if 0
+/* we cannot use this approach on systems where we can't access 16/32 bit
+   data on un-aligned addresses */
+#define DNS__16BIT(p)                   ntohs(*(unsigned short*)(p))
+#define DNS__32BIT(p)                   ntohl(*(unsigned long*)(p))
+#define DNS__SET16BIT(p, v)             *(unsigned short*)(p) = htons(v)
+#define DNS__SET32BIT(p, v)             *(unsigned long*)(p) = htonl(v)
+#endif
+
+/* Macros for parsing a DNS header */
+#define DNS_HEADER_QID(h)               DNS__16BIT(h)
+#define DNS_HEADER_QR(h)                (((h)[2] >> 7) & 0x1)
+#define DNS_HEADER_OPCODE(h)            (((h)[2] >> 3) & 0xf)
+#define DNS_HEADER_AA(h)                (((h)[2] >> 2) & 0x1)
+#define DNS_HEADER_TC(h)                (((h)[2] >> 1) & 0x1)
+#define DNS_HEADER_RD(h)                ((h)[2] & 0x1)
+#define DNS_HEADER_RA(h)                (((h)[3] >> 7) & 0x1)
+#define DNS_HEADER_Z(h)                 (((h)[3] >> 4) & 0x7)
+#define DNS_HEADER_RCODE(h)             ((h)[3] & 0xf)
+#define DNS_HEADER_QDCOUNT(h)           DNS__16BIT((h) + 4)
+#define DNS_HEADER_ANCOUNT(h)           DNS__16BIT((h) + 6)
+#define DNS_HEADER_NSCOUNT(h)           DNS__16BIT((h) + 8)
+#define DNS_HEADER_ARCOUNT(h)           DNS__16BIT((h) + 10)
+
+/* Macros for constructing a DNS header */
+#define DNS_HEADER_SET_QID(h, v)      DNS__SET16BIT(h, v)
+#define DNS_HEADER_SET_QR(h, v)       ((h)[2] |= (unsigned char)(((v) & 0x1) << 7))
+#define DNS_HEADER_SET_OPCODE(h, v)   ((h)[2] |= (unsigned char)(((v) & 0xf) << 3))
+#define DNS_HEADER_SET_AA(h, v)       ((h)[2] |= (unsigned char)(((v) & 0x1) << 2))
+#define DNS_HEADER_SET_TC(h, v)       ((h)[2] |= (unsigned char)(((v) & 0x1) << 1))
+#define DNS_HEADER_SET_RD(h, v)       ((h)[2] |= (unsigned char)((v) & 0x1))
+#define DNS_HEADER_SET_RA(h, v)       ((h)[3] |= (unsigned char)(((v) & 0x1) << 7))
+#define DNS_HEADER_SET_Z(h, v)        ((h)[3] |= (unsigned char)(((v) & 0x7) << 4))
+#define DNS_HEADER_SET_RCODE(h, v)    ((h)[3] |= (unsigned char)((v) & 0xf))
+#define DNS_HEADER_SET_QDCOUNT(h, v)  DNS__SET16BIT((h) + 4, v)
+#define DNS_HEADER_SET_ANCOUNT(h, v)  DNS__SET16BIT((h) + 6, v)
+#define DNS_HEADER_SET_NSCOUNT(h, v)  DNS__SET16BIT((h) + 8, v)
+#define DNS_HEADER_SET_ARCOUNT(h, v)  DNS__SET16BIT((h) + 10, v)
+
+/* Macros for parsing the fixed part of a DNS question */
+#define DNS_QUESTION_TYPE(q)            DNS__16BIT(q)
+#define DNS_QUESTION_CLASS(q)           DNS__16BIT((q) + 2)
+
+/* Macros for constructing the fixed part of a DNS question */
+#define DNS_QUESTION_SET_TYPE(q, v)     DNS__SET16BIT(q, v)
+#define DNS_QUESTION_SET_CLASS(q, v)    DNS__SET16BIT((q) + 2, v)
+
+/* Macros for parsing the fixed part of a DNS resource record */
+#define DNS_RR_TYPE(r)                  DNS__16BIT(r)
+#define DNS_RR_CLASS(r)                 DNS__16BIT((r) + 2)
+#define DNS_RR_TTL(r)                   DNS__32BIT((r) + 4)
+#define DNS_RR_LEN(r)                   DNS__16BIT((r) + 8)
+
+/* Macros for constructing the fixed part of a DNS resource record */
+#define DNS_RR_SET_TYPE(r)              DNS__SET16BIT(r, v)
+#define DNS_RR_SET_CLASS(r)             DNS__SET16BIT((r) + 2, v)
+#define DNS_RR_SET_TTL(r)               DNS__SET32BIT((r) + 4, v)
+#define DNS_RR_SET_LEN(r)               DNS__SET16BIT((r) + 8, v)
+
+#endif /* ARES__DNS_H */
diff --git a/3rdParty/CAres/src/ares_expand_name.c b/3rdParty/CAres/src/ares_expand_name.c
new file mode 100644
index 0000000..75e88e8
--- /dev/null
+++ b/3rdParty/CAres/src/ares_expand_name.c
@@ -0,0 +1,190 @@
+/* $Id: ares_expand_name.c,v 1.20 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h" /* for the memdebug */
+
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+                       int alen);
+
+/* Expand an RFC1035-encoded domain name given by encoded.  The
+ * containing message is given by abuf and alen.  The result given by
+ * *s, which is set to a NUL-terminated allocated buffer.  *enclen is
+ * set to the length of the encoded name (not the length of the
+ * expanded name; the goal is to tell the caller how many bytes to
+ * move forward to get past the encoded name).
+ *
+ * In the simple case, an encoded name is a series of labels, each
+ * composed of a one-byte length (limited to values between 0 and 63
+ * inclusive) followed by the label contents.  The name is terminated
+ * by a zero-length label.
+ *
+ * In the more complicated case, a label may be terminated by an
+ * indirection pointer, specified by two bytes with the high bits of
+ * the first byte (corresponding to INDIR_MASK) set to 11.  With the
+ * two high bits of the first byte stripped off, the indirection
+ * pointer gives an offset from the beginning of the containing
+ * message with more labels to decode.  Indirection can happen an
+ * arbitrary number of times, so we have to detect loops.
+ *
+ * Since the expanded name uses '.' as a label separator, we use
+ * backslashes to escape periods or backslashes in the expanded name.
+ */
+
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+                     int alen, char **s, long *enclen)
+{
+  int len, indir = 0;
+  char *q;
+  const unsigned char *p;
+
+  len = name_length(encoded, abuf, alen);
+  if (len < 0)
+    return ARES_EBADNAME;
+
+  *s = malloc(((size_t)len) + 1);
+  if (!*s)
+    return ARES_ENOMEM;
+  q = *s;
+
+  if (len == 0) {
+    /* RFC2181 says this should be ".": the root of the DNS tree.
+     * Since this function strips trailing dots though, it becomes ""
+     */
+    q[0] = '\0';
+    *enclen = 1;  /* the caller should move one byte to get past this */
+    return ARES_SUCCESS;
+  }
+
+  /* No error-checking necessary; it was all done by name_length(). */
+  p = encoded;
+  while (*p)
+    {
+      if ((*p & INDIR_MASK) == INDIR_MASK)
+        {
+          if (!indir)
+            {
+              *enclen = p + 2 - encoded;
+              indir = 1;
+            }
+          p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
+        }
+      else
+        {
+          len = *p;
+          p++;
+          while (len--)
+            {
+              if (*p == '.' || *p == '\\')
+                *q++ = '\\';
+              *q++ = *p;
+              p++;
+            }
+          *q++ = '.';
+        }
+    }
+  if (!indir)
+    *enclen = p + 1 - encoded;
+
+  /* Nuke the trailing period if we wrote one. */
+  if (q > *s)
+    *(q - 1) = 0;
+  else
+    *q = 0; /* zero terminate */
+
+  return ARES_SUCCESS;
+}
+
+/* Return the length of the expansion of an encoded domain name, or
+ * -1 if the encoding is invalid.
+ */
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+                       int alen)
+{
+  int n = 0, offset, indir = 0;
+
+  /* Allow the caller to pass us abuf + alen and have us check for it. */
+  if (encoded == abuf + alen)
+    return -1;
+
+  while (*encoded)
+    {
+      if ((*encoded & INDIR_MASK) == INDIR_MASK)
+        {
+          /* Check the offset and go there. */
+          if (encoded + 1 >= abuf + alen)
+            return -1;
+          offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
+          if (offset >= alen)
+            return -1;
+          encoded = abuf + offset;
+
+          /* If we've seen more indirects than the message length,
+           * then there's a loop.
+           */
+          if (++indir > alen)
+            return -1;
+        }
+      else
+        {
+          offset = *encoded;
+          if (encoded + offset + 1 >= abuf + alen)
+            return -1;
+          encoded++;
+          while (offset--)
+            {
+              n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
+              encoded++;
+            }
+          n++;
+        }
+    }
+
+  /* If there were any labels at all, then the number of dots is one
+   * less than the number of labels, so subtract one.
+   */
+  return (n) ? n - 1 : n;
+}
+
+/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
+int ares__expand_name_for_response(const unsigned char *encoded,
+                                   const unsigned char *abuf, int alen,
+                                   char **s, long *enclen)
+{
+  int status = ares_expand_name(encoded, abuf, alen, s, enclen);
+  if (status == ARES_EBADNAME)
+    status = ARES_EBADRESP;
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares_expand_string.c b/3rdParty/CAres/src/ares_expand_string.c
new file mode 100644
index 0000000..c72bb62
--- /dev/null
+++ b/3rdParty/CAres/src/ares_expand_string.c
@@ -0,0 +1,72 @@
+/* $Id: ares_expand_string.c,v 1.10 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h" /* for the memdebug */
+
+/* Simply decodes a length-encoded character string. The first byte of the
+ * input is the length of the string to be returned and the bytes thereafter
+ * are the characters of the string. The returned result will be NULL
+ * terminated.
+ */
+int ares_expand_string(const unsigned char *encoded,
+                       const unsigned char *abuf,
+                       int alen,
+                       unsigned char **s,
+                       long *enclen)
+{
+  unsigned char *q;
+  long len;
+  if (encoded == abuf+alen)
+    return ARES_EBADSTR;
+
+  len = *encoded;
+  if (encoded+len+1 > abuf+alen)
+    return ARES_EBADSTR;
+
+  encoded++;
+
+  *s = malloc(len+1);
+  if (*s == NULL)
+    return ARES_ENOMEM;
+  q = *s;
+  strncpy((char *)q, (char *)encoded, len);
+  q[len] = '\0';
+
+  *s = q;
+
+  *enclen = len+1;
+
+  return ARES_SUCCESS;
+}
+
diff --git a/3rdParty/CAres/src/ares_fds.c b/3rdParty/CAres/src/ares_fds.c
new file mode 100644
index 0000000..6ffe9c7
--- /dev/null
+++ b/3rdParty/CAres/src/ares_fds.c
@@ -0,0 +1,63 @@
+/* $Id: ares_fds.c,v 1.12 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
+{
+  struct server_state *server;
+  ares_socket_t nfds;
+  int i;
+
+  /* Are there any active queries? */
+  int active_queries = !ares__is_list_empty(&(channel->all_queries));
+
+  nfds = 0;
+  for (i = 0; i < channel->nservers; i++)
+    {
+      server = &channel->servers[i];
+      /* We only need to register interest in UDP sockets if we have
+       * outstanding queries.
+       */
+      if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
+        {
+          FD_SET(server->udp_socket, read_fds);
+          if (server->udp_socket >= nfds)
+            nfds = server->udp_socket + 1;
+        }
+      /* We always register for TCP events, because we want to know
+       * when the other side closes the connection, so we don't waste
+       * time trying to use a broken connection.
+       */
+      if (server->tcp_socket != ARES_SOCKET_BAD)
+       {
+         FD_SET(server->tcp_socket, read_fds);
+         if (server->qhead)
+           FD_SET(server->tcp_socket, write_fds);
+         if (server->tcp_socket >= nfds)
+           nfds = server->tcp_socket + 1;
+	}
+    }
+  return (int)nfds;
+}
diff --git a/3rdParty/CAres/src/ares_free_hostent.c b/3rdParty/CAres/src/ares_free_hostent.c
new file mode 100644
index 0000000..c0794ee
--- /dev/null
+++ b/3rdParty/CAres/src/ares_free_hostent.c
@@ -0,0 +1,40 @@
+/* $Id: ares_free_hostent.c,v 1.12 2009-11-09 12:56:50 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <stdlib.h>
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h" /* for memdebug */
+
+void ares_free_hostent(struct hostent *host)
+{
+  char **p;
+
+  free((char *)(host->h_name));
+  for (p = host->h_aliases; *p; p++)
+    free(*p);
+  free(host->h_aliases);
+  free(host->h_addr_list[0]); /* no matter if there is one or many entries,
+                                 there is only one malloc for all of them */
+  free(host->h_addr_list);
+  free(host);
+}
diff --git a/3rdParty/CAres/src/ares_free_string.c b/3rdParty/CAres/src/ares_free_string.c
new file mode 100644
index 0000000..38f98f9
--- /dev/null
+++ b/3rdParty/CAres/src/ares_free_string.c
@@ -0,0 +1,26 @@
+/* $Id: ares_free_string.c,v 1.7 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 2000 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h"
+
+void ares_free_string(void *str)
+{
+  free(str);
+}
diff --git a/3rdParty/CAres/src/ares_gethostbyaddr.c b/3rdParty/CAres/src/ares_gethostbyaddr.c
new file mode 100644
index 0000000..732a031
--- /dev/null
+++ b/3rdParty/CAres/src/ares_gethostbyaddr.c
@@ -0,0 +1,291 @@
+/* $Id: ares_gethostbyaddr.c,v 1.35 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+
+struct addr_query {
+  /* Arguments passed to ares_gethostbyaddr() */
+  ares_channel channel;
+  struct ares_addr addr;
+  ares_host_callback callback;
+  void *arg;
+
+  const char *remaining_lookups;
+  int timeouts;
+};
+
+static void next_lookup(struct addr_query *aquery);
+static void addr_callback(void *arg, int status, int timeouts,
+                          unsigned char *abuf, int alen);
+static void end_aquery(struct addr_query *aquery, int status,
+                       struct hostent *host);
+static int file_lookup(struct ares_addr *addr, struct hostent **host);
+static void ptr_rr_name(char *name, const struct ares_addr *addr);
+
+void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
+                        int family, ares_host_callback callback, void *arg)
+{
+  struct addr_query *aquery;
+
+  if (family != AF_INET && family != AF_INET6)
+    {
+      callback(arg, ARES_ENOTIMP, 0, NULL);
+      return;
+    }
+
+  if ((family == AF_INET && addrlen != sizeof(struct in_addr)) ||
+      (family == AF_INET6 && addrlen != sizeof(struct in6_addr)))
+    {
+      callback(arg, ARES_ENOTIMP, 0, NULL);
+      return;
+    }
+
+  aquery = malloc(sizeof(struct addr_query));
+  if (!aquery)
+    {
+      callback(arg, ARES_ENOMEM, 0, NULL);
+      return;
+    }
+  aquery->channel = channel;
+  if (family == AF_INET)
+    memcpy(&aquery->addr.addrV4, addr, sizeof(struct in_addr));
+  else
+    memcpy(&aquery->addr.addrV6, addr, sizeof(struct in6_addr));
+  aquery->addr.family = family;
+  aquery->callback = callback;
+  aquery->arg = arg;
+  aquery->remaining_lookups = channel->lookups;
+  aquery->timeouts = 0;
+
+  next_lookup(aquery);
+}
+
+static void next_lookup(struct addr_query *aquery)
+{
+  const char *p;
+  char name[128];
+  int status;
+  struct hostent *host;
+
+  for (p = aquery->remaining_lookups; *p; p++)
+    {
+      switch (*p)
+        {
+        case 'b':
+          ptr_rr_name(name, &aquery->addr);
+          aquery->remaining_lookups = p + 1;
+          ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
+                     aquery);
+          return;
+        case 'f':
+          status = file_lookup(&aquery->addr, &host);
+
+          /* this status check below previously checked for !ARES_ENOTFOUND,
+             but we should not assume that this single error code is the one
+             that can occur, as that is in fact no longer the case */
+          if (status == ARES_SUCCESS)
+            {
+              end_aquery(aquery, status, host);
+              return;
+            }
+          break;
+        }
+    }
+  end_aquery(aquery, ARES_ENOTFOUND, NULL);
+}
+
+static void addr_callback(void *arg, int status, int timeouts,
+                          unsigned char *abuf, int alen)
+{
+  struct addr_query *aquery = (struct addr_query *) arg;
+  struct hostent *host;
+  size_t addrlen;
+
+  aquery->timeouts += timeouts;
+  if (status == ARES_SUCCESS)
+    {
+      if (aquery->addr.family == AF_INET)
+        {
+          addrlen = sizeof(struct in_addr);
+          status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4,
+                                        (int)addrlen, AF_INET, &host);
+        }
+      else
+        {
+          addrlen = sizeof(struct in6_addr);
+          status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV6,
+                                        (int)addrlen, AF_INET6, &host);
+        }
+      end_aquery(aquery, status, host);
+    }
+  else if (status == ARES_EDESTRUCTION)
+    end_aquery(aquery, status, NULL);
+  else
+    next_lookup(aquery);
+}
+
+static void end_aquery(struct addr_query *aquery, int status,
+                       struct hostent *host)
+{
+  aquery->callback(aquery->arg, status, aquery->timeouts, host);
+  if (host)
+    ares_free_hostent(host);
+  free(aquery);
+}
+
+static int file_lookup(struct ares_addr *addr, struct hostent **host)
+{
+  FILE *fp;
+  int status;
+  int error;
+
+#ifdef WIN32
+  char PATH_HOSTS[MAX_PATH];
+  if (IS_NT()) {
+    char tmp[MAX_PATH];
+    HKEY hkeyHosts;
+
+    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts)
+        == ERROR_SUCCESS)
+    {
+      DWORD dwLength = MAX_PATH;
+      RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
+                      &dwLength);
+      ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH);
+      RegCloseKey(hkeyHosts);
+    }
+  }
+  else
+    GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
+
+  strcat(PATH_HOSTS, WIN_PATH_HOSTS);
+
+#elif defined(WATT32)
+  extern const char *_w32_GetHostsFile (void);
+  const char *PATH_HOSTS = _w32_GetHostsFile();
+
+  if (!PATH_HOSTS)
+    return ARES_ENOTFOUND;
+#endif
+
+  fp = fopen(PATH_HOSTS, "r");
+  if (!fp)
+    {
+      error = ERRNO;
+      switch(error)
+        {
+        case ENOENT:
+        case ESRCH:
+          return ARES_ENOTFOUND;
+        default:
+          DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                         error, strerror(error)));
+          DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+                         PATH_HOSTS));
+          *host = NULL;
+          return ARES_EFILE;
+        }
+    }
+  while ((status = ares__get_hostent(fp, addr->family, host)) == ARES_SUCCESS)
+    {
+      if (addr->family != (*host)->h_addrtype)
+        {
+          ares_free_hostent(*host);
+          continue;
+        }
+      if (addr->family == AF_INET)
+        {
+          if (memcmp((*host)->h_addr, &addr->addrV4, sizeof(struct in_addr)) == 0)
+            break;
+        }
+      else if (addr->family == AF_INET6)
+        {
+          if (memcmp((*host)->h_addr, &addr->addrV6, sizeof(struct in6_addr)) == 0)
+            break;
+        }
+      ares_free_hostent(*host);
+    }
+  fclose(fp);
+  if (status == ARES_EOF)
+    status = ARES_ENOTFOUND;
+  if (status != ARES_SUCCESS)
+    *host = NULL;
+  return status;
+}
+
+static void ptr_rr_name(char *name, const struct ares_addr *addr)
+{
+  if (addr->family == AF_INET)
+    {
+       unsigned long laddr = ntohl(addr->addrV4.s_addr);
+       int a1 = (int)((laddr >> 24) & 0xff);
+       int a2 = (int)((laddr >> 16) & 0xff);
+       int a3 = (int)((laddr >> 8) & 0xff);
+       int a4 = (int)(laddr & 0xff);
+       sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
+    }
+  else
+    {
+       unsigned char *bytes = (unsigned char *)&addr->addrV6.s6_addr;
+       /* There are too many arguments to do this in one line using
+        * minimally C89-compliant compilers */
+       sprintf(name,
+                "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.",
+                bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
+                bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
+                bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
+                bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4);
+       sprintf(name+strlen(name),
+                "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
+                bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
+                bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
+                bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
+                bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4);
+    }
+}
diff --git a/3rdParty/CAres/src/ares_gethostbyname.c b/3rdParty/CAres/src/ares_gethostbyname.c
new file mode 100644
index 0000000..fc66c6f
--- /dev/null
+++ b/3rdParty/CAres/src/ares_gethostbyname.c
@@ -0,0 +1,511 @@
+/* $Id: ares_gethostbyname.c,v 1.50 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "bitncmp.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+
+struct host_query {
+  /* Arguments passed to ares_gethostbyname() */
+  ares_channel channel;
+  char *name;
+  ares_host_callback callback;
+  void *arg;
+  int sent_family; /* this family is what was is being used */
+  int want_family; /* this family is what is asked for in the API */
+  const char *remaining_lookups;
+  int timeouts;
+};
+
+static void next_lookup(struct host_query *hquery, int status_code);
+static void host_callback(void *arg, int status, int timeouts,
+                          unsigned char *abuf, int alen);
+static void end_hquery(struct host_query *hquery, int status,
+                       struct hostent *host);
+static int fake_hostent(const char *name, int family,
+                        ares_host_callback callback, void *arg);
+static int file_lookup(const char *name, int family, struct hostent **host);
+static void sort_addresses(struct hostent *host,
+                           const struct apattern *sortlist, int nsort);
+static void sort6_addresses(struct hostent *host,
+                            const struct apattern *sortlist, int nsort);
+static int get_address_index(const struct in_addr *addr,
+                             const struct apattern *sortlist, int nsort);
+static int get6_address_index(const struct in6_addr *addr,
+                              const struct apattern *sortlist, int nsort);
+
+void ares_gethostbyname(ares_channel channel, const char *name, int family,
+                        ares_host_callback callback, void *arg)
+{
+  struct host_query *hquery;
+
+  /* Right now we only know how to look up Internet addresses - and unspec
+     means try both basically. */
+  switch (family) {
+  case AF_INET:
+  case AF_INET6:
+  case AF_UNSPEC:
+    break;
+  default:
+    callback(arg, ARES_ENOTIMP, 0, NULL);
+    return;
+  }
+
+  if (fake_hostent(name, family, callback, arg))
+    return;
+
+  /* Allocate and fill in the host query structure. */
+  hquery = malloc(sizeof(struct host_query));
+  if (!hquery)
+    {
+      callback(arg, ARES_ENOMEM, 0, NULL);
+      return;
+    }
+  hquery->channel = channel;
+  hquery->name = strdup(name);
+  hquery->want_family = family;
+  hquery->sent_family = -1; /* nothing is sent yet */
+  if (!hquery->name) {
+    free(hquery);
+    callback(arg, ARES_ENOMEM, 0, NULL);
+    return;
+  }
+  hquery->callback = callback;
+  hquery->arg = arg;
+  hquery->remaining_lookups = channel->lookups;
+  hquery->timeouts = 0;
+
+  /* Start performing lookups according to channel->lookups. */
+  next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
+}
+
+static void next_lookup(struct host_query *hquery, int status_code)
+{
+  const char *p;
+  struct hostent *host;
+  int status = status_code;
+
+  for (p = hquery->remaining_lookups; *p; p++)
+    {
+      switch (*p)
+        {
+        case 'b':
+          /* DNS lookup */
+          hquery->remaining_lookups = p + 1;
+          if ((hquery->want_family == AF_INET6) ||
+              (hquery->want_family == AF_UNSPEC)) {
+            /* if inet6 or unspec, start out with AAAA */
+            hquery->sent_family = AF_INET6;
+            ares_search(hquery->channel, hquery->name, C_IN, T_AAAA,
+                        host_callback, hquery);
+          }
+          else {
+            hquery->sent_family = AF_INET;
+            ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
+                        hquery);
+          }
+          return;
+
+        case 'f':
+          /* Host file lookup */
+          status = file_lookup(hquery->name, hquery->want_family, &host);
+
+          /* this status check below previously checked for !ARES_ENOTFOUND,
+             but we should not assume that this single error code is the one
+             that can occur, as that is in fact no longer the case */
+          if (status == ARES_SUCCESS)
+            {
+              end_hquery(hquery, status, host);
+              return;
+            }
+          status = status_code;   /* Use original status code */
+          break;
+        }
+    }
+  end_hquery(hquery, status, NULL);
+}
+
+static void host_callback(void *arg, int status, int timeouts,
+                          unsigned char *abuf, int alen)
+{
+  struct host_query *hquery = (struct host_query *) arg;
+  ares_channel channel = hquery->channel;
+  struct hostent *host = NULL;
+
+  hquery->timeouts += timeouts;
+  if (status == ARES_SUCCESS)
+    {
+      if (hquery->sent_family == AF_INET)
+        {
+          status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
+          if (host && channel->nsort)
+            sort_addresses(host, channel->sortlist, channel->nsort);
+        }
+      else if (hquery->sent_family == AF_INET6)
+        {
+          status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
+          if (status == ARES_ENODATA || status == ARES_EBADRESP) {
+            /* The query returned something but either there were no AAAA records (e.g. just CNAME) 
+               or the response was malformed.  Try looking up A instead.  
+               We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */
+            hquery->sent_family = AF_INET;
+            ares_search(hquery->channel, hquery->name, C_IN, T_A,
+                        host_callback, hquery);
+            return;
+          }
+          if (host && channel->nsort)
+            sort6_addresses(host, channel->sortlist, channel->nsort);
+        }
+      end_hquery(hquery, status, host);
+    }
+  else if ((status == ARES_ENODATA || status == ARES_EBADRESP || status == ARES_ETIMEOUT) && hquery->sent_family == AF_INET6)
+    {
+      /* The AAAA query yielded no useful result.  Now look up an A instead.  
+         We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */
+      hquery->sent_family = AF_INET;
+      ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
+                  hquery);
+    }
+  else if (status == ARES_EDESTRUCTION)
+    end_hquery(hquery, status, NULL);
+  else
+    next_lookup(hquery, status);
+}
+
+static void end_hquery(struct host_query *hquery, int status,
+                       struct hostent *host)
+{
+  hquery->callback(hquery->arg, status, hquery->timeouts, host);
+  if (host)
+    ares_free_hostent(host);
+  free(hquery->name);
+  free(hquery);
+}
+
+/* If the name looks like an IP address, fake up a host entry, end the
+ * query immediately, and return true.  Otherwise return false.
+ */
+static int fake_hostent(const char *name, int family, ares_host_callback callback,
+                        void *arg)
+{
+  struct hostent hostent;
+  char *aliases[1] = { NULL };
+  char *addrs[2];
+  int result = 0;
+  struct in_addr in;
+  struct in6_addr in6;
+
+  if (family == AF_INET || family == AF_INET6)
+    {
+      /* It only looks like an IP address if it's all numbers and dots. */
+      int numdots = 0, valid = 1;
+      const char *p;
+      for (p = name; *p; p++)
+        {
+          if (!ISDIGIT(*p) && *p != '.') {
+            valid = 0;
+            break;
+          } else if (*p == '.') {
+            numdots++;
+          }
+        }
+
+      /* if we don't have 3 dots, it is illegal
+       * (although inet_addr doesn't think so).
+       */
+      if (numdots != 3 || !valid)
+        result = 0;
+      else
+        result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
+
+      if (result)
+        family = AF_INET;
+    }
+  if (family == AF_INET6)
+    result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
+
+  if (!result)
+    return 0;
+
+  if (family == AF_INET)
+    {
+      hostent.h_length = (int)sizeof(struct in_addr);
+      addrs[0] = (char *)&in;
+    }
+  else if (family == AF_INET6)
+    {
+      hostent.h_length = (int)sizeof(struct in6_addr);
+      addrs[0] = (char *)&in6;
+    }
+  /* Duplicate the name, to avoid a constness violation. */
+  hostent.h_name = strdup(name);
+  if (!hostent.h_name)
+    {
+      callback(arg, ARES_ENOMEM, 0, NULL);
+      return 1;
+    }
+
+  /* Fill in the rest of the host structure and terminate the query. */
+  addrs[1] = NULL;
+  hostent.h_aliases = aliases;
+  hostent.h_addrtype = family;
+  hostent.h_addr_list = addrs;
+  callback(arg, ARES_SUCCESS, 0, &hostent);
+
+  free((char *)(hostent.h_name));
+  return 1;
+}
+
+/* This is an API method */
+int ares_gethostbyname_file(ares_channel channel, const char *name,
+                            int family, struct hostent **host)
+{
+  int result;
+
+  /* We only take the channel to ensure that ares_init() been called. */
+  if(channel == NULL)
+    {
+      /* Anything will do, really.  This seems fine, and is consistent with
+         other error cases. */
+      *host = NULL;
+      return ARES_ENOTFOUND;
+    }
+
+  /* Just chain to the internal implementation we use here; it's exactly
+   * what we want.
+   */
+  result = file_lookup(name, family, host);
+  if(result != ARES_SUCCESS)
+    {
+      /* We guarantee a NULL hostent on failure. */
+      *host = NULL;
+    }
+  return result;
+}
+
+static int file_lookup(const char *name, int family, struct hostent **host)
+{
+  FILE *fp;
+  char **alias;
+  int status;
+  int error;
+
+#ifdef WIN32
+  char PATH_HOSTS[MAX_PATH];
+  if (IS_NT()) {
+    char tmp[MAX_PATH];
+    HKEY hkeyHosts;
+
+    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts)
+        == ERROR_SUCCESS)
+    {
+      DWORD dwLength = MAX_PATH;
+      RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
+                      &dwLength);
+      ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH);
+      RegCloseKey(hkeyHosts);
+    }
+  }
+  else
+    GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
+
+  strcat(PATH_HOSTS, WIN_PATH_HOSTS);
+
+#elif defined(WATT32)
+  extern const char *_w32_GetHostsFile (void);
+  const char *PATH_HOSTS = _w32_GetHostsFile();
+
+  if (!PATH_HOSTS)
+    return ARES_ENOTFOUND;
+#endif
+
+  fp = fopen(PATH_HOSTS, "r");
+  if (!fp)
+    {
+      error = ERRNO;
+      switch(error)
+        {
+        case ENOENT:
+        case ESRCH:
+          return ARES_ENOTFOUND;
+        default:
+          DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                         error, strerror(error)));
+          DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+                         PATH_HOSTS));
+          *host = NULL;
+          return ARES_EFILE;
+        }
+    }
+  while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
+    {
+      if (strcasecmp((*host)->h_name, name) == 0)
+        break;
+      for (alias = (*host)->h_aliases; *alias; alias++)
+        {
+          if (strcasecmp(*alias, name) == 0)
+            break;
+        }
+      if (*alias)
+        break;
+      ares_free_hostent(*host);
+    }
+  fclose(fp);
+  if (status == ARES_EOF)
+    status = ARES_ENOTFOUND;
+  if (status != ARES_SUCCESS)
+    *host = NULL;
+  return status;
+}
+
+static void sort_addresses(struct hostent *host, const struct apattern *sortlist,
+                           int nsort)
+{
+  struct in_addr a1, a2;
+  int i1, i2, ind1, ind2;
+
+  /* This is a simple insertion sort, not optimized at all.  i1 walks
+   * through the address list, with the loop invariant that everything
+   * to the left of i1 is sorted.  In the loop body, the value at i1 is moved
+   * back through the list (via i2) until it is in sorted order.
+   */
+  for (i1 = 0; host->h_addr_list[i1]; i1++)
+    {
+      memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
+      ind1 = get_address_index(&a1, sortlist, nsort);
+      for (i2 = i1 - 1; i2 >= 0; i2--)
+        {
+          memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
+          ind2 = get_address_index(&a2, sortlist, nsort);
+          if (ind2 <= ind1)
+            break;
+          memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
+        }
+      memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
+    }
+}
+
+/* Find the first entry in sortlist which matches addr.  Return nsort
+ * if none of them match.
+ */
+static int get_address_index(const struct in_addr *addr,
+                             const struct apattern *sortlist,
+                             int nsort)
+{
+  int i;
+
+  for (i = 0; i < nsort; i++)
+    {
+      if (sortlist[i].family != AF_INET)
+        continue;
+      if (sortlist[i].type == PATTERN_MASK)
+        {
+          if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
+              == sortlist[i].addrV4.s_addr)
+            break;
+        }
+      else
+        {
+          if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
+                            sortlist[i].mask.bits))
+            break;
+        }
+    }
+  return i;
+}
+
+static void sort6_addresses(struct hostent *host, const struct apattern *sortlist,
+                           int nsort)
+{
+  struct in6_addr a1, a2;
+  int i1, i2, ind1, ind2;
+
+  /* This is a simple insertion sort, not optimized at all.  i1 walks
+   * through the address list, with the loop invariant that everything
+   * to the left of i1 is sorted.  In the loop body, the value at i1 is moved
+   * back through the list (via i2) until it is in sorted order.
+   */
+  for (i1 = 0; host->h_addr_list[i1]; i1++)
+    {
+      memcpy(&a1, host->h_addr_list[i1], sizeof(struct in6_addr));
+      ind1 = get6_address_index(&a1, sortlist, nsort);
+      for (i2 = i1 - 1; i2 >= 0; i2--)
+        {
+          memcpy(&a2, host->h_addr_list[i2], sizeof(struct in6_addr));
+          ind2 = get6_address_index(&a2, sortlist, nsort);
+          if (ind2 <= ind1)
+            break;
+          memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in6_addr));
+        }
+      memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in6_addr));
+    }
+}
+
+/* Find the first entry in sortlist which matches addr.  Return nsort
+ * if none of them match.
+ */
+static int get6_address_index(const struct in6_addr *addr,
+                              const struct apattern *sortlist,
+                              int nsort)
+{
+  int i;
+
+  for (i = 0; i < nsort; i++)
+    {
+      if (sortlist[i].family != AF_INET6)
+        continue;
+        if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addrV6.s6_addr, sortlist[i].mask.bits))
+          break;
+    }
+  return i;
+}
diff --git a/3rdParty/CAres/src/ares_getnameinfo.c b/3rdParty/CAres/src/ares_getnameinfo.c
new file mode 100644
index 0000000..c1c0b16
--- /dev/null
+++ b/3rdParty/CAres/src/ares_getnameinfo.c
@@ -0,0 +1,409 @@
+/* $Id: ares_getnameinfo.c,v 1.36 2009-11-09 12:56:11 yangtse Exp $ */
+
+/* Copyright 2005 by Dominick Meglio
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+#include "ares_setup.h"
+
+#ifdef HAVE_GETSERVBYPORT_R
+#  if !defined(GETSERVBYPORT_R_ARGS) || \
+     (GETSERVBYPORT_R_ARGS < 4) || (GETSERVBYPORT_R_ARGS > 6)
+#    error "you MUST specifiy a valid number of arguments for getservbyport_r"
+#  endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ares.h"
+#include "ares_ipv6.h"
+#include "inet_ntop.h"
+#include "ares_private.h"
+
+struct nameinfo_query {
+  ares_nameinfo_callback callback;
+  void *arg;
+  union {
+    struct sockaddr_in addr4;
+    struct sockaddr_in6 addr6;
+  } addr;
+  int family;
+  int flags;
+  int timeouts;
+};
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+#define IPBUFSIZ 40+IF_NAMESIZE
+#else
+#define IPBUFSIZ 40
+#endif
+
+static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host);
+static char *lookup_service(unsigned short port, int flags,
+                            char *buf, size_t buflen);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
+                           char *buf, size_t buflen);
+#endif
+static char *ares_striendstr(const char *s1, const char *s2);
+
+void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
+                      ares_socklen_t salen,
+                      int flags, ares_nameinfo_callback callback, void *arg)
+{
+  struct sockaddr_in *addr = NULL;
+  struct sockaddr_in6 *addr6 = NULL;
+  struct nameinfo_query *niquery;
+  unsigned int port = 0;
+
+  /* Verify the buffer size */
+  if (salen == sizeof(struct sockaddr_in))
+    {
+      addr = (struct sockaddr_in *)sa;
+      port = addr->sin_port;
+    }
+  else if (salen == sizeof(struct sockaddr_in6))
+    {
+      addr6 = (struct sockaddr_in6 *)sa;
+      port = addr6->sin6_port;
+    }
+  else
+    {
+      callback(arg, ARES_ENOTIMP, 0, NULL, NULL);
+      return;
+    }
+
+  /* If neither, assume they want a host */
+  if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+    flags |= ARES_NI_LOOKUPHOST;
+
+  /* All they want is a service, no need for DNS */
+  if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
+    {
+      char buf[33], *service;
+
+      service = lookup_service((unsigned short)(port & 0xffff),
+                               flags, buf, sizeof(buf));
+      callback(arg, ARES_SUCCESS, 0, NULL, service);
+      return;
+    }
+
+  /* They want a host lookup */
+  if ((flags & ARES_NI_LOOKUPHOST))
+    {
+     /* A numeric host can be handled without DNS */
+     if ((flags & ARES_NI_NUMERICHOST))
+      {
+        char ipbuf[IPBUFSIZ];
+        char srvbuf[33];
+        char *service = NULL;
+        ipbuf[0] = 0;
+
+        /* Specifying not to lookup a host, but then saying a host
+         * is required has to be illegal.
+         */
+        if (flags & ARES_NI_NAMEREQD)
+          {
+            callback(arg, ARES_EBADFLAGS, 0, NULL, NULL);
+            return;
+          }
+        if (salen == sizeof(struct sockaddr_in6))
+          {
+            ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ);
+            /* If the system supports scope IDs, use it */
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+            append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf));
+#endif
+          }
+        else
+          {
+            ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ);
+          }
+        /* They also want a service */
+        if (flags & ARES_NI_LOOKUPSERVICE)
+          service = lookup_service((unsigned short)(port & 0xffff),
+                                   flags, srvbuf, sizeof(srvbuf));
+        callback(arg, ARES_SUCCESS, 0, ipbuf, service);
+        return;
+      }
+    /* This is where a DNS lookup becomes necessary */
+    else
+      {
+        niquery = malloc(sizeof(struct nameinfo_query));
+        if (!niquery)
+          {
+            callback(arg, ARES_ENOMEM, 0, NULL, NULL);
+            return;
+          }
+        niquery->callback = callback;
+        niquery->arg = arg;
+        niquery->flags = flags;
+        niquery->timeouts = 0;
+        if (sa->sa_family == AF_INET)
+          {
+            niquery->family = AF_INET;
+            memcpy(&niquery->addr.addr4, addr, sizeof(addr));
+            ares_gethostbyaddr(channel, &addr->sin_addr, sizeof(struct in_addr), AF_INET,
+                               nameinfo_callback, niquery);
+          }
+        else
+          {
+            niquery->family = AF_INET6;
+            memcpy(&niquery->addr.addr6, addr6, sizeof(addr6));
+            ares_gethostbyaddr(channel, &addr6->sin6_addr, sizeof(struct in6_addr), AF_INET6,
+                               nameinfo_callback, niquery);
+          }
+      }
+    }
+}
+
+static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host)
+{
+  struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
+  char srvbuf[33];
+  char *service = NULL;
+
+  niquery->timeouts += timeouts;
+  if (status == ARES_SUCCESS)
+    {
+      /* They want a service too */
+      if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+        {
+          if (niquery->family == AF_INET)
+            service = lookup_service(niquery->addr.addr4.sin_port,
+                                     niquery->flags, srvbuf, sizeof(srvbuf));
+          else
+            service = lookup_service(niquery->addr.addr6.sin6_port,
+                                     niquery->flags, srvbuf, sizeof(srvbuf));
+        }
+      /* NOFQDN means we have to strip off the domain name portion.
+         We do this by determining our own domain name, then searching the string
+         for this domain name and removing it.
+       */
+#ifdef HAVE_GETHOSTNAME
+      if (niquery->flags & ARES_NI_NOFQDN)
+        {
+           char buf[255];
+           char *domain;
+           gethostname(buf, 255);
+           if ((domain = strchr(buf, '.')))
+             {
+               char *end = ares_striendstr(host->h_name, domain);
+               if (end)
+                 *end = 0;
+             }
+        }
+#endif
+      niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name),
+                        service);
+      return;
+    }
+  /* We couldn't find the host, but it's OK, we can use the IP */
+  else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD))
+    {
+      char ipbuf[IPBUFSIZ];
+      if (niquery->family == AF_INET)
+        ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ);
+      else
+        {
+          ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+          append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf, sizeof(ipbuf));
+#endif
+        }
+      /* They want a service too */
+      if (niquery->flags & ARES_NI_LOOKUPSERVICE)
+        {
+          if (niquery->family == AF_INET)
+            service = lookup_service(niquery->addr.addr4.sin_port,
+                                     niquery->flags, srvbuf, sizeof(srvbuf));
+          else
+            service = lookup_service(niquery->addr.addr6.sin6_port,
+                                     niquery->flags, srvbuf, sizeof(srvbuf));
+        }
+      niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf, service);
+      return;
+    }
+  niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL);
+  free(niquery);
+}
+
+static char *lookup_service(unsigned short port, int flags,
+                            char *buf, size_t buflen)
+{
+  const char *proto;
+  struct servent *sep;
+#ifdef HAVE_GETSERVBYPORT_R
+  struct servent se;
+#endif
+  char tmpbuf[4096];
+
+  if (port)
+    {
+      if (flags & ARES_NI_NUMERICSERV)
+        sep = NULL;
+      else
+        {
+          if (flags & ARES_NI_UDP)
+            proto = "udp";
+          else if (flags & ARES_NI_SCTP)
+            proto = "sctp";
+          else if (flags & ARES_NI_DCCP)
+            proto = "dccp";
+          else
+            proto = "tcp";
+#ifdef HAVE_GETSERVBYPORT_R
+          sep = &se;
+          memset(tmpbuf, 0, sizeof(tmpbuf));
+#if GETSERVBYPORT_R_ARGS == 6
+          if (getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), &sep) != 0)
+            sep = NULL;
+#elif GETSERVBYPORT_R_ARGS == 5
+          sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
+#elif GETSERVBYPORT_R_ARGS == 4
+          if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
+            sep = NULL;
+#else
+          /* Lets just hope the OS uses TLS! */
+          sep = getservbyport(port, proto);
+#endif
+#else
+          /* Lets just hope the OS uses TLS! */
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+          sep = getservbyport(port, (char*)proto);
+#else
+          sep = getservbyport(port, proto);
+#endif
+#endif
+        }
+      if (sep && sep->s_name)
+        /* get service name */
+        strcpy(tmpbuf, sep->s_name);
+      else
+        /* get port as a string */
+        sprintf(tmpbuf, "%u", (unsigned int)ntohs(port));
+      if (strlen(tmpbuf) < buflen)
+        /* return it if buffer big enough */
+        strcpy(buf, tmpbuf);
+      else
+        /* avoid reusing previous one */
+        buf[0] = '\0';
+      return buf;
+    }
+  buf[0] = '\0';
+  return NULL;
+}
+
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
+                           char *buf, size_t buflen)
+{
+#ifdef HAVE_IF_INDEXTONAME
+  int is_ll, is_mcll;
+#endif
+  char fmt_u[] = "%u";
+  char fmt_lu[] = "%lu";
+  char tmpbuf[IF_NAMESIZE + 2];
+  size_t bufl;
+  char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?fmt_lu:fmt_u;
+
+  tmpbuf[0] = '%';
+
+#ifdef HAVE_IF_INDEXTONAME
+  is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr);
+  is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr);
+  if ((flags & ARES_NI_NUMERICSCOPE) ||
+      (!is_ll && !is_mcll))
+    {
+       sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+    }
+  else
+    {
+      if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
+        sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+    }
+#else
+  sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+  (void) flags;
+#endif
+  tmpbuf[IF_NAMESIZE + 1] = '\0';
+  bufl = strlen(buf);
+
+  if(bufl + strlen(tmpbuf) < buflen)
+    /* only append the scopeid string if it fits in the target buffer */
+    strcpy(&buf[bufl], tmpbuf);
+}
+#endif
+
+/* Determines if s1 ends with the string in s2 (case-insensitive) */
+static char *ares_striendstr(const char *s1, const char *s2)
+{
+  const char *c1, *c2, *c1_begin;
+  int lo1, lo2;
+  size_t s1_len = strlen(s1), s2_len = strlen(s2);
+
+  /* If the substr is longer than the full str, it can't match */
+  if (s2_len > s1_len)
+    return NULL;
+
+  /* Jump to the end of s1 minus the length of s2 */
+  c1_begin = s1+s1_len-s2_len;
+  c1 = (const char *)c1_begin;
+  c2 = s2;
+  while (c2 < s2+s2_len)
+    {
+      lo1 = tolower(*c1);
+      lo2 = tolower(*c2);
+      if (lo1 != lo2)
+        return NULL;
+      else
+        {
+          c1++;
+          c2++;
+        }
+    }
+  if (c2 == c1 && c2 == NULL)
+    return (char *)c1_begin;
+  return NULL;
+}
diff --git a/3rdParty/CAres/src/ares_getopt.c b/3rdParty/CAres/src/ares_getopt.c
new file mode 100644
index 0000000..67e1be7
--- /dev/null
+++ b/3rdParty/CAres/src/ares_getopt.c
@@ -0,0 +1,123 @@
+/*
+ * Original file name getopt.c  Initial import into the c-ares source tree
+ * on 2007-04-11.  Lifted from version 5.2 of the 'Open Mash' project with
+ * the modified BSD license, BSD license without the advertising clause.
+ *
+ * $Id: ares_getopt.c,v 1.9 2009-11-22 03:41:26 yangtse Exp $
+ */
+
+/*
+ * getopt.c --
+ *
+ *      Standard UNIX getopt function.  Code is from BSD.
+ *
+ * Copyright (c) 1987-2001 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * A. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * B. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * C. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* #if !defined(lint)
+ * static char sccsid[] = "@(#)getopt.c 8.2 (Berkeley) 4/2/94";
+ * #endif
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ares_getopt.h"
+
+int   opterr = 1,     /* if error message should be printed */
+      optind = 1;     /* index into parent argv vector */
+int   optopt = 0;     /* character checked for validity */
+static int optreset;  /* reset getopt */
+char  *optarg;        /* argument associated with option */
+
+#define  BADCH   (int)'?'
+#define  BADARG  (int)':'
+#define  EMSG    (char *)""
+
+/*
+ * ares_getopt --
+ *    Parse argc/argv argument vector.
+ */
+int
+ares_getopt(int nargc, char * const nargv[], const char *ostr)
+{
+    static char *place = EMSG;                /* option letter processing */
+    char *oli;                                /* option letter list index */
+
+    if (optreset || !*place) {                /* update scanning pointer */
+        optreset = 0;
+        if (optind >= nargc || *(place = nargv[optind]) != '-') {
+            place = EMSG;
+            return (EOF);
+        }
+        if (place[1] && *++place == '-') {    /* found "--" */
+            ++optind;
+            place = EMSG;
+            return (EOF);
+        }
+    }                                         /* option letter okay? */
+    if ((optopt = (int)*place++) == (int)':' ||
+        (oli = strchr(ostr, optopt)) == NULL) {
+        /*
+         * if the user didn't specify '-' as an option,
+         * assume it means EOF.
+         */
+        if (optopt == (int)'-')
+            return (EOF);
+        if (!*place)
+            ++optind;
+        if (opterr && *ostr != ':')
+            (void)fprintf(stderr,
+                "%s: illegal option -- %c\n", __FILE__, optopt);
+        return (BADCH);
+    }
+    if (*++oli != ':') {                      /* don't need argument */
+        optarg = NULL;
+        if (!*place)
+            ++optind;
+    }
+    else {                                    /* need an argument */
+        if (*place)                           /* no white space */
+            optarg = place;
+        else if (nargc <= ++optind) {         /* no arg */
+            place = EMSG;
+            if (*ostr == ':')
+                return (BADARG);
+            if (opterr)
+                (void)fprintf(stderr,
+                    "%s: option requires an argument -- %c\n",
+                    __FILE__, optopt);
+            return (BADCH);
+        }
+         else                                 /* white space */
+            optarg = nargv[optind];
+        place = EMSG;
+        ++optind;
+    }
+    return (optopt);                          /* dump back option letter */
+}
diff --git a/3rdParty/CAres/src/ares_getopt.h b/3rdParty/CAres/src/ares_getopt.h
new file mode 100644
index 0000000..63acb3b
--- /dev/null
+++ b/3rdParty/CAres/src/ares_getopt.h
@@ -0,0 +1,53 @@
+#ifndef ARES_GETOPT_H
+#define ARES_GETOPT_H
+
+/*
+ * Copyright (c) 1987-2001 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * A. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * B. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * C. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+int ares_getopt(int nargc, char * const nargv[], const char *ostr);
+
+#undef optarg
+#undef optind
+#undef opterr
+#undef optopt
+#undef optreset
+
+#define optarg   ares_optarg
+#define optind   ares_optind
+#define opterr   ares_opterr
+#define optopt   ares_optopt
+#define optreset ares_optreset
+
+extern char *optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+
+#endif /* ARES_GETOPT_H */
diff --git a/3rdParty/CAres/src/ares_getsock.c b/3rdParty/CAres/src/ares_getsock.c
new file mode 100644
index 0000000..a25b83a
--- /dev/null
+++ b/3rdParty/CAres/src/ares_getsock.c
@@ -0,0 +1,75 @@
+/* $Id: ares_getsock.c,v 1.8 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright (C) 2005 - 2007, Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+int ares_getsock(ares_channel channel,
+                 int *s,
+                 int numsocks) /* size of the 'socks' array */
+{
+  struct server_state *server;
+  int i;
+  int sockindex=0;
+  int bitmap = 0;
+  unsigned int setbits = 0xffffffff;
+
+  ares_socket_t *socks = (ares_socket_t *)s;
+
+  /* Are there any active queries? */
+  int active_queries = !ares__is_list_empty(&(channel->all_queries));
+
+  for (i = 0;
+       (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
+       i++)
+    {
+      server = &channel->servers[i];
+      /* We only need to register interest in UDP sockets if we have
+       * outstanding queries.
+       */
+      if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
+        {
+          if(sockindex >= numsocks)
+            break;
+          socks[sockindex] = server->udp_socket;
+          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
+          sockindex++;
+        }
+      /* We always register for TCP events, because we want to know
+       * when the other side closes the connection, so we don't waste
+       * time trying to use a broken connection.
+       */
+      if (server->tcp_socket != ARES_SOCKET_BAD)
+       {
+         if(sockindex >= numsocks)
+           break;
+         socks[sockindex] = server->tcp_socket;
+         bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
+
+         if (server->qhead && active_queries)
+           /* then the tcp socket is also writable! */
+           bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
+
+         sockindex++;
+       }
+    }
+  return bitmap;
+}
diff --git a/3rdParty/CAres/src/ares_init.c b/3rdParty/CAres/src/ares_init.c
new file mode 100644
index 0000000..cb541af
--- /dev/null
+++ b/3rdParty/CAres/src/ares_init.c
@@ -0,0 +1,1582 @@
+/* $Id: ares_init.c,v 1.103 2009-11-18 10:33:54 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef USE_WINSOCK
+#include <iphlpapi.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <errno.h>
+#include "ares.h"
+#include "inet_net_pton.h"
+#include "ares_library_init.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32  /* Redefined in MingW/MSVC headers */
+#endif
+
+static int init_by_options(ares_channel channel, const struct ares_options *options,
+                           int optmask);
+static int init_by_environment(ares_channel channel);
+static int init_by_resolv_conf(ares_channel channel);
+static int init_by_defaults(ares_channel channel);
+
+#ifndef WATT32
+static int config_nameserver(struct server_state **servers, int *nservers,
+                             char *str);
+#endif
+static int set_search(ares_channel channel, const char *str);
+static int set_options(ares_channel channel, const char *str);
+static const char *try_option(const char *p, const char *q, const char *opt);
+static int init_id_key(rc4_key* key,int key_data_len);
+
+#if !defined(WIN32) && !defined(WATT32)
+static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
+static int ip_addr(const char *s, int len, struct in_addr *addr);
+static void natural_mask(struct apattern *pat);
+static int config_domain(ares_channel channel, char *str);
+static int config_lookup(ares_channel channel, const char *str,
+                         const char *bindch, const char *filech);
+static int config_sortlist(struct apattern **sortlist, int *nsort,
+                           const char *str);
+static char *try_config(char *s, const char *opt);
+#endif
+
+#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
+                             x->nservers > -1 && \
+                             x->ndomains > -1 && \
+                             x->ndots > -1 && x->timeout > -1 && \
+                             x->tries > -1)
+
+int ares_init(ares_channel *channelptr)
+{
+  return ares_init_options(channelptr, NULL, 0);
+}
+
+int ares_init_options(ares_channel *channelptr, struct ares_options *options,
+                      int optmask)
+{
+  ares_channel channel;
+  int i;
+  int status = ARES_SUCCESS;
+  struct server_state *server;
+  struct timeval now;
+
+#ifdef CURLDEBUG
+  const char *env = getenv("CARES_MEMDEBUG");
+
+  if (env)
+    curl_memdebug(env);
+  env = getenv("CARES_MEMLIMIT");
+  if (env)
+    curl_memlimit(atoi(env));
+#endif
+
+  if (ares_library_initialized() != ARES_SUCCESS)
+    return ARES_ENOTINITIALIZED;
+
+  channel = malloc(sizeof(struct ares_channeldata));
+  if (!channel) {
+    *channelptr = NULL;
+    return ARES_ENOMEM;
+  }
+
+  now = ares__tvnow();
+
+  /* Set everything to distinguished values so we know they haven't
+   * been set yet.
+   */
+  channel->flags = -1;
+  channel->timeout = -1;
+  channel->tries = -1;
+  channel->ndots = -1;
+  channel->rotate = -1;
+  channel->udp_port = -1;
+  channel->tcp_port = -1;
+  channel->socket_send_buffer_size = -1;
+  channel->socket_receive_buffer_size = -1;
+  channel->nservers = -1;
+  channel->ndomains = -1;
+  channel->nsort = -1;
+  channel->tcp_connection_generation = 0;
+  channel->lookups = NULL;
+  channel->domains = NULL;
+  channel->sortlist = NULL;
+  channel->servers = NULL;
+  channel->sock_state_cb = NULL;
+  channel->sock_state_cb_data = NULL;
+  channel->sock_create_cb = NULL;
+  channel->sock_create_cb_data = NULL;
+
+  channel->last_server = 0;
+  channel->last_timeout_processed = (time_t)now.tv_sec;
+
+  /* Initialize our lists of queries */
+  ares__init_list_head(&(channel->all_queries));
+  for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
+    {
+      ares__init_list_head(&(channel->queries_by_qid[i]));
+    }
+  for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
+    {
+      ares__init_list_head(&(channel->queries_by_timeout[i]));
+    }
+
+  /* Initialize configuration by each of the four sources, from highest
+   * precedence to lowest.
+   */
+
+  if (status == ARES_SUCCESS) {
+    status = init_by_options(channel, options, optmask);
+    if (status != ARES_SUCCESS)
+      DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
+                     ares_strerror(status)));
+  }
+  if (status == ARES_SUCCESS) {
+    status = init_by_environment(channel);
+    if (status != ARES_SUCCESS)
+      DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
+                     ares_strerror(status)));
+  }
+  if (status == ARES_SUCCESS) {
+    status = init_by_resolv_conf(channel);
+    if (status != ARES_SUCCESS)
+      DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
+                     ares_strerror(status)));
+  }
+
+  /*
+   * No matter what failed or succeeded, seed defaults to provide
+   * useful behavior for things that we missed.
+   */
+  status = init_by_defaults(channel);
+  if (status != ARES_SUCCESS)
+    DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
+                   ares_strerror(status)));
+
+  /* Generate random key */
+
+  if (status == ARES_SUCCESS) {
+    status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
+    if (status == ARES_SUCCESS)
+      channel->next_id = ares__generate_new_id(&channel->id_key);
+    else
+      DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
+                     ares_strerror(status)));
+  }
+
+  if (status != ARES_SUCCESS)
+    {
+      /* Something failed; clean up memory we may have allocated. */
+      if (channel->servers)
+        free(channel->servers);
+      if (channel->domains)
+        {
+          for (i = 0; i < channel->ndomains; i++)
+            free(channel->domains[i]);
+          free(channel->domains);
+        }
+      if (channel->sortlist)
+        free(channel->sortlist);
+      if(channel->lookups)
+        free(channel->lookups);
+      free(channel);
+      return status;
+    }
+
+  /* Trim to one server if ARES_FLAG_PRIMARY is set. */
+  if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
+    channel->nservers = 1;
+
+  /* Initialize server states. */
+  for (i = 0; i < channel->nservers; i++)
+    {
+      server = &channel->servers[i];
+      server->udp_socket = ARES_SOCKET_BAD;
+      server->tcp_socket = ARES_SOCKET_BAD;
+      server->tcp_connection_generation = ++channel->tcp_connection_generation;
+      server->tcp_lenbuf_pos = 0;
+      server->tcp_buffer = NULL;
+      server->qhead = NULL;
+      server->qtail = NULL;
+      ares__init_list_head(&(server->queries_to_server));
+      server->channel = channel;
+      server->is_broken = 0;
+    }
+
+  *channelptr = channel;
+  return ARES_SUCCESS;
+}
+
+/* ares_dup() duplicates a channel handle with all its options and returns a
+   new channel handle */
+int ares_dup(ares_channel *dest, ares_channel src)
+{
+  struct ares_options opts;
+  int rc;
+  int optmask;
+
+  *dest = NULL; /* in case of failure return NULL explicitly */
+
+  /* First get the options supported by the old ares_save_options() function,
+     which is most of them */
+  rc = ares_save_options(src, &opts, &optmask);
+  if(rc)
+    return rc;
+
+  /* Then create the new channel with those options */
+  rc = ares_init_options(dest, &opts, optmask);
+
+  /* destroy the options copy to not leak any memory */
+  ares_destroy_options(&opts);
+
+  if(rc)
+    return rc;
+
+  /* Now clone the options that ares_save_options() doesn't support. */
+  (*dest)->sock_create_cb      = src->sock_create_cb;
+  (*dest)->sock_create_cb_data = src->sock_create_cb_data;
+
+
+  return ARES_SUCCESS; /* everything went fine */
+
+}
+
+/* Save options from initialized channel */
+int ares_save_options(ares_channel channel, struct ares_options *options,
+                      int *optmask)
+{
+  int i;
+
+  /* Zero everything out */
+  memset(options, 0, sizeof(struct ares_options));
+
+  if (!ARES_CONFIG_CHECK(channel))
+    return ARES_ENODATA;
+
+  /* Traditionally the optmask wasn't saved in the channel struct so it was
+     recreated here. ROTATE is the first option that has no struct field of
+     its own in the public config struct */
+  (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
+                ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
+                ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
+                ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
+    (channel->optmask & ARES_OPT_ROTATE);
+
+  /* Copy easy stuff */
+  options->flags   = channel->flags;
+
+  /* We return full millisecond resolution but that's only because we don't
+     set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
+  options->timeout = channel->timeout;
+  options->tries   = channel->tries;
+  options->ndots   = channel->ndots;
+  options->udp_port = (unsigned short)channel->udp_port;
+  options->tcp_port = (unsigned short)channel->tcp_port;
+  options->sock_state_cb     = channel->sock_state_cb;
+  options->sock_state_cb_data = channel->sock_state_cb_data;
+
+  /* Copy servers */
+  if (channel->nservers) {
+    options->servers =
+      malloc(channel->nservers * sizeof(struct server_state));
+    if (!options->servers && channel->nservers != 0)
+      return ARES_ENOMEM;
+    for (i = 0; i < channel->nservers; i++)
+      options->servers[i] = channel->servers[i].addr;
+  }
+  options->nservers = channel->nservers;
+
+  /* copy domains */
+  if (channel->ndomains) {
+    options->domains = malloc(channel->ndomains * sizeof(char *));
+    if (!options->domains)
+      return ARES_ENOMEM;
+
+    for (i = 0; i < channel->ndomains; i++)
+    {
+      options->ndomains = i;
+      options->domains[i] = strdup(channel->domains[i]);
+      if (!options->domains[i])
+        return ARES_ENOMEM;
+    }
+  }
+  options->ndomains = channel->ndomains;
+
+  /* copy lookups */
+  if (channel->lookups) {
+    options->lookups = strdup(channel->lookups);
+    if (!options->lookups && channel->lookups)
+      return ARES_ENOMEM;
+  }
+
+  /* copy sortlist */
+  if (channel->nsort) {
+    options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
+    if (!options->sortlist)
+      return ARES_ENOMEM;
+    for (i = 0; i < channel->nsort; i++)
+    {
+      memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
+             sizeof(struct apattern));
+    }
+  }
+  options->nsort = channel->nsort;
+
+  return ARES_SUCCESS;
+}
+
+static int init_by_options(ares_channel channel,
+                           const struct ares_options *options,
+                           int optmask)
+{
+  int i;
+
+  /* Easy stuff. */
+  if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
+    channel->flags = options->flags;
+  if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
+    channel->timeout = options->timeout;
+  else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
+    channel->timeout = options->timeout * 1000;
+  if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
+    channel->tries = options->tries;
+  if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
+    channel->ndots = options->ndots;
+  if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
+    channel->rotate = 1;
+  if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
+    channel->udp_port = options->udp_port;
+  if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
+    channel->tcp_port = options->tcp_port;
+  if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
+    {
+      channel->sock_state_cb = options->sock_state_cb;
+      channel->sock_state_cb_data = options->sock_state_cb_data;
+    }
+  if ((optmask & ARES_OPT_SOCK_SNDBUF)
+      && channel->socket_send_buffer_size == -1)
+    channel->socket_send_buffer_size = options->socket_send_buffer_size;
+  if ((optmask & ARES_OPT_SOCK_RCVBUF)
+      && channel->socket_receive_buffer_size == -1)
+    channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
+
+  /* Copy the servers, if given. */
+  if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
+    {
+      /* Avoid zero size allocations at any cost */
+      if (options->nservers > 0)
+        {
+          channel->servers =
+            malloc(options->nservers * sizeof(struct server_state));
+          if (!channel->servers)
+            return ARES_ENOMEM;
+          for (i = 0; i < options->nservers; i++)
+            channel->servers[i].addr = options->servers[i];
+        }
+      channel->nservers = options->nservers;
+    }
+
+  /* Copy the domains, if given.  Keep channel->ndomains consistent so
+   * we can clean up in case of error.
+   */
+  if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
+    {
+      /* Avoid zero size allocations at any cost */
+      if (options->ndomains > 0)
+      {
+        channel->domains = malloc(options->ndomains * sizeof(char *));
+        if (!channel->domains)
+          return ARES_ENOMEM;
+        for (i = 0; i < options->ndomains; i++)
+          {
+            channel->ndomains = i;
+            channel->domains[i] = strdup(options->domains[i]);
+            if (!channel->domains[i])
+              return ARES_ENOMEM;
+          }
+      }
+      channel->ndomains = options->ndomains;
+    }
+
+  /* Set lookups, if given. */
+  if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
+    {
+      channel->lookups = strdup(options->lookups);
+      if (!channel->lookups)
+        return ARES_ENOMEM;
+    }
+
+  /* copy sortlist */
+  if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
+    {
+      channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
+      if (!channel->sortlist)
+        return ARES_ENOMEM;
+      for (i = 0; i < options->nsort; i++)
+        {
+          memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
+                 sizeof(struct apattern));
+        }
+      channel->nsort = options->nsort;
+    }
+
+  channel->optmask = optmask;
+
+  return ARES_SUCCESS;
+}
+
+static int init_by_environment(ares_channel channel)
+{
+  const char *localdomain, *res_options;
+  int status;
+
+  localdomain = getenv("LOCALDOMAIN");
+  if (localdomain && channel->ndomains == -1)
+    {
+      status = set_search(channel, localdomain);
+      if (status != ARES_SUCCESS)
+        return status;
+    }
+
+  res_options = getenv("RES_OPTIONS");
+  if (res_options)
+    {
+      status = set_options(channel, res_options);
+      if (status != ARES_SUCCESS)
+        return status;
+    }
+
+  return ARES_SUCCESS;
+}
+
+#ifdef WIN32
+/*
+ * Warning: returns a dynamically allocated buffer, the user MUST
+ * use free() if the function returns 1
+ */
+static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
+{
+  /* Test for the size we need */
+  DWORD size = 0;
+  int result;
+
+  result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
+  if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
+    return 0;
+  *obuf = malloc(size+1);
+  if (!*obuf)
+    return 0;
+
+  if (RegQueryValueEx(hKey, subkey, 0, NULL,
+                      (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
+  {
+    free(*obuf);
+    return 0;
+  }
+  if (size == 1)
+  {
+    free(*obuf);
+    return 0;
+  }
+  return 1;
+}
+
+static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
+{
+  char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
+  DWORD enum_size = 39;
+  int idx = 0;
+  HKEY hVal;
+
+  while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
+                      NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
+  {
+    int rc;
+
+    enum_size = 39;
+    if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
+        ERROR_SUCCESS)
+      continue;
+    rc = get_res_nt(hVal, subkey, obuf);
+      RegCloseKey(hVal);
+    if (rc)
+      return 1;
+    }
+  return 0;
+}
+
+static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
+{
+  FIXED_INFO    *fi, *newfi;
+  DWORD          size = sizeof (*fi);
+  IP_ADDR_STRING *ipAddr;
+  int            i, count = 0;
+  int            debug  = 0;
+  size_t         ip_size = sizeof("255.255.255.255,")-1;
+  size_t         left = ret_size;
+  char          *ret = ret_buf;
+  HRESULT        res;
+
+  fi = malloc(size);
+  if (!fi)
+     return 0;
+
+  res = (*ares_fpGetNetworkParams) (fi, &size);
+  if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
+     goto quit;
+
+  newfi = realloc(fi, size);
+  if (!newfi)
+     goto quit;
+
+  fi = newfi;
+  res = (*ares_fpGetNetworkParams) (fi, &size);
+  if (res != ERROR_SUCCESS)
+     goto quit;
+
+  if (debug)
+  {
+    printf ("Host Name: %s\n", fi->HostName);
+    printf ("Domain Name: %s\n", fi->DomainName);
+    printf ("DNS Servers:\n"
+            "    %s (primary)\n", fi->DnsServerList.IpAddress.String);
+  }
+  if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
+      inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
+      left > ip_size)
+  {
+    ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
+    left -= ret - ret_buf;
+    count++;
+  }
+
+  for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
+       ipAddr = ipAddr->Next, i++)
+  {
+    if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
+    {
+       ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
+       left -= ret - ret_buf;
+       count++;
+    }
+    if (debug)
+       printf ("    %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
+  }
+
+quit:
+  if (fi)
+     free(fi);
+
+  if (debug && left <= ip_size)
+     printf ("Too many nameservers. Truncating to %d addressess", count);
+  if (ret > ret_buf)
+     ret[-1] = '\0';
+  return count;
+}
+#endif
+
+static int init_by_resolv_conf(ares_channel channel)
+{
+#ifndef WATT32
+  char *line = NULL;
+#endif
+  int status = -1, nservers = 0, nsort = 0;
+  struct server_state *servers = NULL;
+  struct apattern *sortlist = NULL;
+
+#ifdef WIN32
+
+    /*
+  NameServer info via IPHLPAPI (IP helper API):
+    GetNetworkParams() should be the trusted source for this.
+    Available in Win-98/2000 and later. If that fail, fall-back to
+    registry information.
+
+  NameServer Registry:
+
+   On Windows 9X, the DNS server can be found in:
+HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
+
+        On Windows NT/2000/XP/2003:
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
+        or
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
+        or
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
+NameServer
+        or
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
+DhcpNameServer
+   */
+
+  HKEY mykey;
+  HKEY subkey;
+  DWORD data_type;
+  DWORD bytes;
+  DWORD result;
+  char  buf[256];
+
+  if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
+     return ARES_SUCCESS;
+
+  if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
+  {
+    status = config_nameserver(&servers, &nservers, buf);
+    if (status == ARES_SUCCESS)
+      goto okay;
+  }
+
+  if (IS_NT())
+  {
+    if (RegOpenKeyEx(
+          HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
+          KEY_READ, &mykey
+          ) == ERROR_SUCCESS)
+    {
+      RegOpenKeyEx(mykey, "Interfaces", 0,
+                   KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
+      if (get_res_nt(mykey, NAMESERVER, &line))
+      {
+        status = config_nameserver(&servers, &nservers, line);
+        free(line);
+      }
+      else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
+      {
+        status = config_nameserver(&servers, &nservers, line);
+        free(line);
+      }
+      /* Try the interfaces */
+      else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
+      {
+        status = config_nameserver(&servers, &nservers, line);
+        free(line);
+      }
+      else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
+      {
+        status = config_nameserver(&servers, &nservers, line);
+        free(line);
+      }
+      RegCloseKey(subkey);
+      RegCloseKey(mykey);
+    }
+  }
+  else
+  {
+    if (RegOpenKeyEx(
+          HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
+          KEY_READ, &mykey
+          ) == ERROR_SUCCESS)
+    {
+      if ((result = RegQueryValueEx(
+             mykey, NAMESERVER, NULL, &data_type,
+             NULL, &bytes
+             )
+            ) == ERROR_SUCCESS ||
+          result == ERROR_MORE_DATA)
+      {
+        if (bytes)
+        {
+          line = malloc(bytes+1);
+          if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
+                              (unsigned char *)line, &bytes) ==
+              ERROR_SUCCESS)
+          {
+            status = config_nameserver(&servers, &nservers, line);
+          }
+          free(line);
+        }
+      }
+    }
+    RegCloseKey(mykey);
+  }
+
+  if (status == ARES_SUCCESS)
+    status = ARES_EOF;
+  else
+    /* Catch the case when all the above checks fail (which happens when there
+       is no network card or the cable is unplugged) */
+    status = ARES_EFILE;
+
+#elif defined(__riscos__)
+
+  /* Under RISC OS, name servers are listed in the
+     system variable Inet$Resolvers, space separated. */
+
+  line = getenv("Inet$Resolvers");
+  status = ARES_EOF;
+  if (line) {
+    char *resolvers = strdup(line), *pos, *space;
+
+    if (!resolvers)
+      return ARES_ENOMEM;
+
+    pos = resolvers;
+    do {
+      space = strchr(pos, ' ');
+      if (space)
+        *space = '\0';
+      status = config_nameserver(&servers, &nservers, pos);
+      if (status != ARES_SUCCESS)
+        break;
+      pos = space + 1;
+    } while (space);
+
+    if (status == ARES_SUCCESS)
+      status = ARES_EOF;
+
+    free(resolvers);
+  }
+
+#elif defined(WATT32)
+  int i;
+
+  sock_init();
+  for (i = 0; def_nameservers[i]; i++)
+      ;
+  if (i == 0)
+    return ARES_SUCCESS; /* use localhost DNS server */
+
+  nservers = i;
+  servers = calloc(i, sizeof(struct server_state));
+  if (!servers)
+     return ARES_ENOMEM;
+
+  for (i = 0; def_nameservers[i]; i++)
+      servers[i].addr.s_addr = htonl(def_nameservers[i]);
+  status = ARES_EOF;
+
+#else
+  {
+    char *p;
+    FILE *fp;
+    size_t linesize;
+    int error;
+
+    /* Don't read resolv.conf and friends if we don't have to */
+    if (ARES_CONFIG_CHECK(channel))
+        return ARES_SUCCESS;
+
+    fp = fopen(PATH_RESOLV_CONF, "r");
+    if (fp) {
+      while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+      {
+        if ((p = try_config(line, "domain")) && channel->ndomains == -1)
+          status = config_domain(channel, p);
+        else if ((p = try_config(line, "lookup")) && !channel->lookups)
+          status = config_lookup(channel, p, "bind", "file");
+        else if ((p = try_config(line, "search")) && channel->ndomains == -1)
+          status = set_search(channel, p);
+        else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
+          status = config_nameserver(&servers, &nservers, p);
+        else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
+          status = config_sortlist(&sortlist, &nsort, p);
+        else if ((p = try_config(line, "options")))
+          status = set_options(channel, p);
+        else
+          status = ARES_SUCCESS;
+        if (status != ARES_SUCCESS)
+          break;
+      }
+      fclose(fp);
+    }
+    else {
+      error = ERRNO;
+      switch(error) {
+      case ENOENT:
+      case ESRCH:
+        status = ARES_EOF;
+        break;
+      default:
+        DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                       error, strerror(error)));
+        DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
+        status = ARES_EFILE;
+      }
+    }
+
+    if ((status == ARES_EOF) && (!channel->lookups)) {
+      /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
+      fp = fopen("/etc/nsswitch.conf", "r");
+      if (fp) {
+        while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+        {
+          if ((p = try_config(line, "hosts:")) && !channel->lookups)
+            status = config_lookup(channel, p, "dns", "files");
+        }
+        fclose(fp);
+      }
+      else {
+        error = ERRNO;
+        switch(error) {
+        case ENOENT:
+        case ESRCH:
+          status = ARES_EOF;
+          break;
+        default:
+          DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                         error, strerror(error)));
+          DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
+          status = ARES_EFILE;
+        }
+      }
+    }
+
+    if ((status == ARES_EOF) && (!channel->lookups)) {
+      /* Linux / GNU libc 2.x and possibly others have host.conf */
+      fp = fopen("/etc/host.conf", "r");
+      if (fp) {
+        while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+        {
+          if ((p = try_config(line, "order")) && !channel->lookups)
+            status = config_lookup(channel, p, "bind", "hosts");
+        }
+        fclose(fp);
+      }
+      else {
+        error = ERRNO;
+        switch(error) {
+        case ENOENT:
+        case ESRCH:
+          status = ARES_EOF;
+          break;
+        default:
+          DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                         error, strerror(error)));
+          DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
+          status = ARES_EFILE;
+        }
+      }
+    }
+
+    if ((status == ARES_EOF) && (!channel->lookups)) {
+      /* Tru64 uses /etc/svc.conf */
+      fp = fopen("/etc/svc.conf", "r");
+      if (fp) {
+        while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+        {
+          if ((p = try_config(line, "hosts=")) && !channel->lookups)
+            status = config_lookup(channel, p, "bind", "local");
+        }
+        fclose(fp);
+      }
+      else {
+        error = ERRNO;
+        switch(error) {
+        case ENOENT:
+        case ESRCH:
+          status = ARES_EOF;
+          break;
+        default:
+          DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                         error, strerror(error)));
+          DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
+          status = ARES_EFILE;
+        }
+      }
+    }
+
+    if(line)
+      free(line);
+  }
+
+#endif
+
+  /* Handle errors. */
+  if (status != ARES_EOF)
+    {
+      if (servers != NULL)
+        free(servers);
+      if (sortlist != NULL)
+        free(sortlist);
+      return status;
+    }
+
+  /* If we got any name server entries, fill them in. */
+#ifdef WIN32
+okay:
+#endif
+  if (servers)
+    {
+      channel->servers = servers;
+      channel->nservers = nservers;
+    }
+
+  /* If we got any sortlist entries, fill them in. */
+  if (sortlist)
+    {
+      channel->sortlist = sortlist;
+      channel->nsort = nsort;
+    }
+
+  return ARES_SUCCESS;
+}
+
+static int init_by_defaults(ares_channel channel)
+{
+  char *hostname = NULL;
+  int rc = ARES_SUCCESS;
+#ifdef HAVE_GETHOSTNAME
+  char *dot;
+#endif
+
+  if (channel->flags == -1)
+    channel->flags = 0;
+  if (channel->timeout == -1)
+    channel->timeout = DEFAULT_TIMEOUT;
+  if (channel->tries == -1)
+    channel->tries = DEFAULT_TRIES;
+  if (channel->ndots == -1)
+    channel->ndots = 1;
+  if (channel->rotate == -1)
+    channel->rotate = 0;
+  if (channel->udp_port == -1)
+    channel->udp_port = htons(NAMESERVER_PORT);
+  if (channel->tcp_port == -1)
+    channel->tcp_port = htons(NAMESERVER_PORT);
+
+  if (channel->nservers == -1) {
+    /* If nobody specified servers, try a local named. */
+    channel->servers = malloc(sizeof(struct server_state));
+    if (!channel->servers) {
+      rc = ARES_ENOMEM;
+      goto error;
+    }
+    channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
+    channel->nservers = 1;
+  }
+
+#ifdef ENAMETOOLONG
+#define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
+#else
+#define toolong(x) (x == -1) && (EINVAL == errno)
+#endif
+
+  if (channel->ndomains == -1) {
+    /* Derive a default domain search list from the kernel hostname,
+     * or set it to empty if the hostname isn't helpful.
+     */
+    size_t len = 64;
+    int res;
+    channel->ndomains = 0; /* default to none */
+
+#ifdef HAVE_GETHOSTNAME
+    hostname = malloc(len);
+    if(!hostname) {
+      rc = ARES_ENOMEM;
+      goto error;
+    }
+
+    do {
+      res = gethostname(hostname, len);
+
+      if(toolong(res)) {
+        char *p;
+        len *= 2;
+        p = realloc(hostname, len);
+        if(!p) {
+          rc = ARES_ENOMEM;
+          goto error;
+        }
+        hostname = p;
+        continue;
+      }
+      else if(res) {
+        rc = ARES_EBADNAME;
+        goto error;
+      }
+
+    } while(0);
+
+    dot = strchr(hostname, '.');
+    if (dot) {
+      /* a dot was found */
+      channel->domains = malloc(sizeof(char *));
+      if (!channel->domains) {
+        rc = ARES_ENOMEM;
+        goto error;
+      }
+      channel->domains[0] = strdup(dot + 1);
+      if (!channel->domains[0]) {
+        rc = ARES_ENOMEM;
+        goto error;
+      }
+      channel->ndomains = 1;
+    }
+#endif
+  }
+
+  if (channel->nsort == -1) {
+    channel->sortlist = NULL;
+    channel->nsort = 0;
+  }
+
+  if (!channel->lookups) {
+    channel->lookups = strdup("fb");
+    if (!channel->lookups)
+      rc = ARES_ENOMEM;
+  }
+
+  error:
+  if(rc) {
+    if(channel->servers)
+      free(channel->servers);
+
+    if(channel->domains && channel->domains[0])
+      free(channel->domains[0]);
+    if(channel->domains)
+      free(channel->domains);
+    if(channel->lookups)
+      free(channel->lookups);
+  }
+
+  if(hostname)
+    free(hostname);
+
+  return rc;
+}
+
+#if !defined(WIN32) && !defined(WATT32)
+static int config_domain(ares_channel channel, char *str)
+{
+  char *q;
+
+  /* Set a single search domain. */
+  q = str;
+  while (*q && !ISSPACE(*q))
+    q++;
+  *q = '\0';
+  return set_search(channel, str);
+}
+
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
+    defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
+  /* workaround icc 9.1 optimizer issue */
+# define vqualifier volatile
+#else
+# define vqualifier
+#endif
+
+static int config_lookup(ares_channel channel, const char *str,
+                         const char *bindch, const char *filech)
+{
+  char lookups[3], *l;
+  const char *vqualifier p;
+
+  /* Set the lookup order.  Only the first letter of each work
+   * is relevant, and it has to be "b" for DNS or "f" for the
+   * host file.  Ignore everything else.
+   */
+  l = lookups;
+  p = str;
+  while (*p)
+    {
+      if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
+        if (*p == *bindch) *l++ = 'b';
+        else *l++ = 'f';
+      }
+      while (*p && !ISSPACE(*p) && (*p != ','))
+        p++;
+      while (*p && (ISSPACE(*p) || (*p == ',')))
+        p++;
+    }
+  *l = '\0';
+  channel->lookups = strdup(lookups);
+  return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
+}
+#endif  /* !WIN32 & !WATT32 */
+
+#ifndef WATT32
+static int config_nameserver(struct server_state **servers, int *nservers,
+                             char *str)
+{
+  struct in_addr addr;
+  struct server_state *newserv;
+  /* On Windows, there may be more than one nameserver specified in the same
+   * registry key, so we parse it as a space or comma seperated list.
+   */
+#ifdef WIN32
+  char *p = str;
+  char *begin = str;
+  int more = 1;
+  while (more)
+  {
+    more = 0;
+    while (*p && !ISSPACE(*p) && *p != ',')
+      p++;
+
+    if (*p)
+    {
+      *p = '\0';
+      more = 1;
+    }
+
+    /* Skip multiple spaces or trailing spaces */
+    if (!*begin)
+    {
+      begin = ++p;
+      continue;
+    }
+
+    /* This is the part that actually sets the nameserver */
+    addr.s_addr = inet_addr(begin);
+    if (addr.s_addr == INADDR_NONE)
+      continue;
+    newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
+    if (!newserv)
+      return ARES_ENOMEM;
+    newserv[*nservers].addr = addr;
+    *servers = newserv;
+    (*nservers)++;
+
+    if (!more)
+      break;
+    begin = ++p;
+  }
+#else
+  /* Add a nameserver entry, if this is a valid address. */
+  addr.s_addr = inet_addr(str);
+  if (addr.s_addr == INADDR_NONE)
+    return ARES_SUCCESS;
+  newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
+  if (!newserv)
+    return ARES_ENOMEM;
+  newserv[*nservers].addr = addr;
+  *servers = newserv;
+  (*nservers)++;
+#endif
+  return ARES_SUCCESS;
+}
+
+#ifndef WIN32
+static int config_sortlist(struct apattern **sortlist, int *nsort,
+                           const char *str)
+{
+  struct apattern pat;
+  const char *q;
+
+  /* Add sortlist entries. */
+  while (*str && *str != ';')
+    {
+      int bits;
+      char ipbuf[16], ipbufpfx[32];
+      /* Find just the IP */
+      q = str;
+      while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
+        q++;
+      memcpy(ipbuf, str, (int)(q-str));
+      ipbuf[(int)(q-str)] = '\0';
+      /* Find the prefix */
+      if (*q == '/')
+        {
+          const char *str2 = q+1;
+          while (*q && *q != ';' && !ISSPACE(*q))
+            q++;
+          memcpy(ipbufpfx, str, (int)(q-str));
+          ipbufpfx[(int)(q-str)] = '\0';
+          str = str2;
+        }
+      else
+        ipbufpfx[0] = '\0';
+      /* Lets see if it is CIDR */
+      /* First we'll try IPv6 */
+      if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
+                                     &pat.addrV6,
+                                     sizeof(pat.addrV6))) > 0)
+        {
+          pat.type = PATTERN_CIDR;
+          pat.mask.bits = (unsigned short)bits;
+          pat.family = AF_INET6;
+          if (!sortlist_alloc(sortlist, nsort, &pat))
+            return ARES_ENOMEM;
+        }
+      if (ipbufpfx[0] &&
+          (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
+                                     sizeof(pat.addrV4))) > 0)
+        {
+          pat.type = PATTERN_CIDR;
+          pat.mask.bits = (unsigned short)bits;
+          pat.family = AF_INET;
+          if (!sortlist_alloc(sortlist, nsort, &pat))
+            return ARES_ENOMEM;
+        }
+      /* See if it is just a regular IP */
+      else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
+        {
+          if (ipbufpfx[0])
+            {
+              memcpy(ipbuf, str, (int)(q-str));
+              ipbuf[(int)(q-str)] = '\0';
+              if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
+                natural_mask(&pat);
+            }
+          else
+            natural_mask(&pat);
+          pat.family = AF_INET;
+          pat.type = PATTERN_MASK;
+          if (!sortlist_alloc(sortlist, nsort, &pat))
+            return ARES_ENOMEM;
+        }
+      else
+        {
+          while (*q && *q != ';' && !ISSPACE(*q))
+            q++;
+        }
+      str = q;
+      while (ISSPACE(*str))
+        str++;
+    }
+
+  return ARES_SUCCESS;
+}
+#endif  /* !WIN32 */
+#endif  /* !WATT32 */
+
+static int set_search(ares_channel channel, const char *str)
+{
+  int n;
+  const char *p, *q;
+
+  if(channel->ndomains != -1) {
+    /* if we already have some domains present, free them first */
+    for(n=0; n < channel->ndomains; n++)
+      free(channel->domains[n]);
+    free(channel->domains);
+    channel->domains = NULL;
+    channel->ndomains = -1;
+  }
+
+  /* Count the domains given. */
+  n = 0;
+  p = str;
+  while (*p)
+    {
+      while (*p && !ISSPACE(*p))
+        p++;
+      while (ISSPACE(*p))
+        p++;
+      n++;
+    }
+
+  if (!n)
+    {
+      channel->ndomains = 0;
+      return ARES_SUCCESS;
+    }
+
+  channel->domains = malloc(n * sizeof(char *));
+  if (!channel->domains)
+    return ARES_ENOMEM;
+
+  /* Now copy the domains. */
+  n = 0;
+  p = str;
+  while (*p)
+    {
+      channel->ndomains = n;
+      q = p;
+      while (*q && !ISSPACE(*q))
+        q++;
+      channel->domains[n] = malloc(q - p + 1);
+      if (!channel->domains[n])
+        return ARES_ENOMEM;
+      memcpy(channel->domains[n], p, q - p);
+      channel->domains[n][q - p] = 0;
+      p = q;
+      while (ISSPACE(*p))
+        p++;
+      n++;
+    }
+  channel->ndomains = n;
+
+  return ARES_SUCCESS;
+}
+
+static int set_options(ares_channel channel, const char *str)
+{
+  const char *p, *q, *val;
+
+  p = str;
+  while (*p)
+    {
+      q = p;
+      while (*q && !ISSPACE(*q))
+        q++;
+      val = try_option(p, q, "ndots:");
+      if (val && channel->ndots == -1)
+        channel->ndots = atoi(val);
+      val = try_option(p, q, "retrans:");
+      if (val && channel->timeout == -1)
+        channel->timeout = atoi(val);
+      val = try_option(p, q, "retry:");
+      if (val && channel->tries == -1)
+        channel->tries = atoi(val);
+      val = try_option(p, q, "rotate");
+      if (val && channel->rotate == -1)
+        channel->rotate = 1;
+      p = q;
+      while (ISSPACE(*p))
+        p++;
+    }
+
+  return ARES_SUCCESS;
+}
+
+static const char *try_option(const char *p, const char *q, const char *opt)
+{
+  size_t len = strlen(opt);
+  return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
+}
+
+#if !defined(WIN32) && !defined(WATT32)
+static char *try_config(char *s, const char *opt)
+{
+  size_t len;
+  char *p;
+  char *q;
+
+  if (!s || !opt)
+    /* no line or no option */
+    return NULL;
+
+  /* trim line comment */
+  p = s;
+  while (*p && (*p != '#'))
+    p++;
+  *p = '\0';
+
+  /* trim trailing whitespace */
+  q = p - 1;
+  while ((q >= s) && ISSPACE(*q))
+    q--;
+  *++q = '\0';
+
+  /* skip leading whitespace */
+  p = s;
+  while (*p && ISSPACE(*p))
+    p++;
+
+  if (!*p)
+    /* empty line */
+    return NULL;
+
+  if ((len = strlen(opt)) == 0)
+    /* empty option */
+    return NULL;
+
+  if (strncmp(p, opt, len) != 0)
+    /* line and option do not match */
+    return NULL;
+
+  /* skip over given option name */
+  p += len;
+
+  if (!*p)
+    /* no option value */
+    return NULL;
+
+  if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
+    /* whitespace between option name and value is mandatory
+       for given option names which do not end with ':' or '=' */
+    return NULL;
+
+  /* skip over whitespace */
+  while (*p && ISSPACE(*p))
+    p++;
+
+  if (!*p)
+    /* no option value */
+    return NULL;
+
+  /* return pointer to option value */
+  return p;
+}
+
+static int sortlist_alloc(struct apattern **sortlist, int *nsort,
+                          struct apattern *pat)
+{
+  struct apattern *newsort;
+  newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
+  if (!newsort)
+    return 0;
+  newsort[*nsort] = *pat;
+  *sortlist = newsort;
+  (*nsort)++;
+  return 1;
+}
+
+static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
+{
+
+  /* Four octets and three periods yields at most 15 characters. */
+  if (len > 15)
+    return -1;
+
+  addr->s_addr = inet_addr(ipbuf);
+  if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
+    return -1;
+  return 0;
+}
+
+static void natural_mask(struct apattern *pat)
+{
+  struct in_addr addr;
+
+  /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
+   * but portable.
+   */
+  addr.s_addr = ntohl(pat->addrV4.s_addr);
+
+  /* This is out of date in the CIDR world, but some people might
+   * still rely on it.
+   */
+  if (IN_CLASSA(addr.s_addr))
+    pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
+  else if (IN_CLASSB(addr.s_addr))
+    pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
+  else
+    pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
+}
+#endif /* !WIN32 && !WATT32 */
+
+/* initialize an rc4 key. If possible a cryptographically secure random key
+   is generated using a suitable function (for example win32's RtlGenRandom as
+   described in
+   http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
+   otherwise the code defaults to cross-platform albeit less secure mechanism
+   using rand
+*/
+static void randomize_key(unsigned char* key,int key_data_len)
+{
+  int randomized = 0;
+  int counter=0;
+#ifdef WIN32
+  BOOLEAN res;
+  if (ares_fpSystemFunction036)
+    {
+      res = (*ares_fpSystemFunction036) (key, key_data_len);
+      if (res)
+        randomized = 1;
+    }
+#else /* !WIN32 */
+#ifdef RANDOM_FILE
+  FILE *f = fopen(RANDOM_FILE, "rb");
+  if(f) {
+    counter = fread(key, 1, key_data_len, f);
+    fclose(f);
+  }
+#endif
+#endif /* WIN32 */
+
+  if ( !randomized ) {
+    for (;counter<key_data_len;counter++)
+      key[counter]=(unsigned char)(rand() % 256);
+  }
+}
+
+static int init_id_key(rc4_key* key,int key_data_len)
+{
+  unsigned char index1;
+  unsigned char index2;
+  unsigned char* state;
+  short counter;
+  unsigned char *key_data_ptr = 0;
+
+  key_data_ptr = calloc(1,key_data_len);
+  if (!key_data_ptr)
+    return ARES_ENOMEM;
+
+  state = &key->state[0];
+  for(counter = 0; counter < 256; counter++)
+    /* unnecessary AND but it keeps some compilers happier */
+    state[counter] = (unsigned char)(counter & 0xff);
+  randomize_key(key->state,key_data_len);
+  key->x = 0;
+  key->y = 0;
+  index1 = 0;
+  index2 = 0;
+  for(counter = 0; counter < 256; counter++)
+  {
+    index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
+                              index2) % 256);
+    ARES_SWAP_BYTE(&state[counter], &state[index2]);
+
+    index1 = (unsigned char)((index1 + 1) % key_data_len);
+  }
+  free(key_data_ptr);
+  return ARES_SUCCESS;
+}
+
+unsigned short ares__generate_new_id(rc4_key* key)
+{
+  unsigned short r=0;
+  ares__rc4(key, (unsigned char *)&r, sizeof(r));
+  return r;
+}
+
+void ares_set_socket_callback(ares_channel channel,
+                              ares_sock_create_callback cb,
+                              void *data)
+{
+  channel->sock_create_cb = cb;
+  channel->sock_create_cb_data = data;
+}
diff --git a/3rdParty/CAres/src/ares_ipv6.h b/3rdParty/CAres/src/ares_ipv6.h
new file mode 100644
index 0000000..18914d1
--- /dev/null
+++ b/3rdParty/CAres/src/ares_ipv6.h
@@ -0,0 +1,84 @@
+/* $Id: ares_ipv6.h,v 1.9 2009-05-02 02:36:48 yangtse Exp $ */
+
+/* Copyright (C) 2005 by Dominick Meglio
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES_IPV6_H
+#define ARES_IPV6_H
+
+#ifndef HAVE_PF_INET6
+#define PF_INET6 AF_INET6
+#endif
+
+#if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr)
+struct in6_addr {
+  union {
+    unsigned char _S6_u8[16];
+  } _S6_un;
+};
+#define s6_addr _S6_un._S6_u8
+#endif
+
+#ifndef HAVE_STRUCT_SOCKADDR_IN6
+struct sockaddr_in6
+{
+  unsigned short  sin6_family;
+  unsigned short  sin6_port;
+  unsigned long   sin6_flowinfo;
+  struct in6_addr sin6_addr;
+  unsigned int    sin6_scope_id;
+};
+#endif
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo
+{
+  int              ai_flags;
+  int              ai_family;
+  int              ai_socktype;
+  int              ai_protocol;
+  ares_socklen_t   ai_addrlen;   /* Follow rfc3493 struct addrinfo */
+  char            *ai_canonname;
+  struct sockaddr *ai_addr;
+  struct addrinfo *ai_next;
+};
+#endif
+
+#ifndef NS_IN6ADDRSZ
+#if SIZEOF_STRUCT_IN6_ADDR == 0
+/* We cannot have it set to zero, so we pick a fixed value here */
+#define NS_IN6ADDRSZ 16
+#else
+#define NS_IN6ADDRSZ SIZEOF_STRUCT_IN6_ADDR
+#endif
+#endif
+
+#ifndef NS_INADDRSZ
+#define NS_INADDRSZ SIZEOF_STRUCT_IN_ADDR
+#endif
+
+#ifndef NS_INT16SZ
+#define NS_INT16SZ 2
+#endif
+
+#ifndef IF_NAMESIZE
+#ifdef IFNAMSIZ
+#define IF_NAMESIZE IFNAMSIZ
+#else
+#define IF_NAMESIZE 256
+#endif
+#endif
+
+#endif /* ARES_IPV6_H */
diff --git a/3rdParty/CAres/src/ares_library_init.c b/3rdParty/CAres/src/ares_library_init.c
new file mode 100644
index 0000000..049cfa4
--- /dev/null
+++ b/3rdParty/CAres/src/ares_library_init.c
@@ -0,0 +1,133 @@
+/* $Id: ares_library_init.c,v 1.11 2009-11-11 08:56:47 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#include "ares.h"
+#include "ares_library_init.h"
+#include "ares_private.h"
+
+/* library-private global and unique instance vars */
+
+#ifdef USE_WINSOCK
+fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
+fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
+#endif
+
+/* library-private global vars with source visibility restricted to this file */
+
+static unsigned int ares_initialized;
+static int          ares_init_flags;
+
+#ifdef USE_WINSOCK
+static HMODULE hnd_iphlpapi;
+static HMODULE hnd_advapi32;
+#endif
+
+
+static int ares_win32_init(void)
+{
+#ifdef USE_WINSOCK
+
+  hnd_iphlpapi = 0;
+  hnd_iphlpapi = LoadLibrary("iphlpapi.dll");
+  if (!hnd_iphlpapi)
+    return ARES_ELOADIPHLPAPI;
+
+  ares_fpGetNetworkParams = (fpGetNetworkParams_t)
+    GetProcAddress(hnd_iphlpapi, "GetNetworkParams");
+  if (!ares_fpGetNetworkParams)
+    {
+      FreeLibrary(hnd_iphlpapi);
+      return ARES_EADDRGETNETWORKPARAMS;
+    }
+
+  /*
+   * When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
+   * also known as RtlGenRandom, which is the case for Windows versions prior
+   * to WinXP then c-ares uses portable rand() function. Then don't error here.
+   */
+
+  hnd_advapi32 = 0;
+  hnd_advapi32 = LoadLibrary("advapi32.dll");
+  if (hnd_advapi32)
+    {
+      ares_fpSystemFunction036 = (fpSystemFunction036_t)
+        GetProcAddress(hnd_advapi32, "SystemFunction036");
+    }
+
+#endif
+  return ARES_SUCCESS;
+}
+
+
+static void ares_win32_cleanup(void)
+{
+#ifdef USE_WINSOCK
+  if (hnd_advapi32)
+    FreeLibrary(hnd_advapi32);
+  if (hnd_iphlpapi)
+    FreeLibrary(hnd_iphlpapi);
+#endif
+}
+
+
+int ares_library_init(int flags)
+{
+  int res;
+
+  if (ares_initialized)
+    return ARES_SUCCESS;
+  ares_initialized++;
+
+  if (flags & ARES_LIB_INIT_WIN32)
+    {
+      res = ares_win32_init();
+      if (res != ARES_SUCCESS)
+        return res;
+    }
+
+  ares_init_flags = flags;
+
+  return ARES_SUCCESS;
+}
+
+
+void ares_library_cleanup(void)
+{
+  if (!ares_initialized)
+    return;
+  ares_initialized--;
+
+  if (ares_init_flags & ARES_LIB_INIT_WIN32)
+    ares_win32_cleanup();
+
+  ares_init_flags = ARES_LIB_INIT_NONE;
+}
+
+
+int ares_library_initialized(void)
+{
+#ifdef USE_WINSOCK
+  if (!ares_initialized)
+    return ARES_ENOTINITIALIZED;
+#endif
+  return ARES_SUCCESS;
+}
+
+
diff --git a/3rdParty/CAres/src/ares_library_init.h b/3rdParty/CAres/src/ares_library_init.h
new file mode 100644
index 0000000..a81d855
--- /dev/null
+++ b/3rdParty/CAres/src/ares_library_init.h
@@ -0,0 +1,40 @@
+#ifndef HEADER_CARES_LIBRARY_INIT_H
+#define HEADER_CARES_LIBRARY_INIT_H
+
+/* $Id: ares_library_init.h,v 1.5 2009-11-11 08:56:47 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef USE_WINSOCK
+
+#include <iphlpapi.h>
+
+typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
+typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
+
+/* Forward-declaration of variables defined in ares_library_init.c */
+/* that are global and unique instances for whole c-ares library.  */
+
+extern fpGetNetworkParams_t ares_fpGetNetworkParams;
+extern fpSystemFunction036_t ares_fpSystemFunction036;
+
+#endif /* USE_WINSOCK */
+
+#endif /* HEADER_CARES_LIBRARY_INIT_H */
+
diff --git a/3rdParty/CAres/src/ares_llist.c b/3rdParty/CAres/src/ares_llist.c
new file mode 100644
index 0000000..c820ed1
--- /dev/null
+++ b/3rdParty/CAres/src/ares_llist.c
@@ -0,0 +1,87 @@
+/* $Id: ares_llist.c,v 1.2 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#include "ares.h"
+#include "ares_private.h"
+
+/* Routines for managing doubly-linked circular linked lists with a
+ * dummy head.
+ */
+
+/* Initialize a new head node */
+void ares__init_list_head(struct list_node* head) {
+  head->prev = head;
+  head->next = head;
+  head->data = NULL;
+}
+
+/* Initialize a list node */
+void ares__init_list_node(struct list_node* node, void* d) {
+  node->prev = NULL;
+  node->next = NULL;
+  node->data = d;
+}
+
+/* Returns true iff the given list is empty */
+int ares__is_list_empty(struct list_node* head) {
+  return ((head->next == head) && (head->prev == head));
+}
+
+/* Inserts new_node before old_node */
+void ares__insert_in_list(struct list_node* new_node,
+                          struct list_node* old_node) {
+  new_node->next = old_node;
+  new_node->prev = old_node->prev;
+  old_node->prev->next = new_node;
+  old_node->prev = new_node;
+}
+
+/* Removes the node from the list it's in, if any */
+void ares__remove_from_list(struct list_node* node) {
+  if (node->next != NULL) {
+    node->prev->next = node->next;
+    node->next->prev = node->prev;
+    node->prev = NULL;
+    node->next = NULL;
+  }
+}
+
+/* Swap the contents of two lists */
+void ares__swap_lists(struct list_node* head_a,
+                      struct list_node* head_b) {
+  int is_a_empty = ares__is_list_empty(head_a);
+  int is_b_empty = ares__is_list_empty(head_b);
+  struct list_node old_a = *head_a;
+  struct list_node old_b = *head_b;
+
+  if (is_a_empty) {
+    ares__init_list_head(head_b);
+  } else {
+    *head_b = old_a;
+    old_a.next->prev = head_b;
+    old_a.prev->next = head_b;
+  }
+  if (is_b_empty) {
+    ares__init_list_head(head_a);
+  } else {
+    *head_a = old_b;
+    old_b.next->prev = head_a;
+    old_b.prev->next = head_a;
+  }
+}
diff --git a/3rdParty/CAres/src/ares_llist.h b/3rdParty/CAres/src/ares_llist.h
new file mode 100644
index 0000000..4875b3f
--- /dev/null
+++ b/3rdParty/CAres/src/ares_llist.h
@@ -0,0 +1,43 @@
+#ifndef __ARES_LLIST_H
+#define __ARES_LLIST_H
+
+/* $Id: ares_llist.h,v 1.1 2007-10-02 02:18:01 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+/* Node definition for circular, doubly-linked list */
+struct list_node {
+  struct list_node *prev;
+  struct list_node *next;
+  void* data;
+};
+
+void ares__init_list_head(struct list_node* head);
+
+void ares__init_list_node(struct list_node* node, void* d);
+
+int ares__is_list_empty(struct list_node* head);
+
+void ares__insert_in_list(struct list_node* new_node,
+                          struct list_node* old_node);
+
+void ares__remove_from_list(struct list_node* node);
+
+void ares__swap_lists(struct list_node* head_a,
+                      struct list_node* head_b);
+
+#endif /* __ARES_LLIST_H */
diff --git a/3rdParty/CAres/src/ares_mkquery.c b/3rdParty/CAres/src/ares_mkquery.c
new file mode 100644
index 0000000..04d2b6d
--- /dev/null
+++ b/3rdParty/CAres/src/ares_mkquery.c
@@ -0,0 +1,196 @@
+/* $Id: ares_mkquery.c,v 1.17 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+/* Header format, from RFC 1035:
+ *                                  1  1  1  1  1  1
+ *    0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                      ID                       |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                    QDCOUNT                    |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                    ANCOUNT                    |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                    NSCOUNT                    |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                    ARCOUNT                    |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *
+ * AA, TC, RA, and RCODE are only set in responses.  Brief description
+ * of the remaining fields:
+ *      ID      Identifier to match responses with queries
+ *      QR      Query (0) or response (1)
+ *      Opcode  For our purposes, always QUERY
+ *      RD      Recursion desired
+ *      Z       Reserved (zero)
+ *      QDCOUNT Number of queries
+ *      ANCOUNT Number of answers
+ *      NSCOUNT Number of name server records
+ *      ARCOUNT Number of additional records
+ *
+ * Question format, from RFC 1035:
+ *                                  1  1  1  1  1  1
+ *    0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                                               |
+ *  /                     QNAME                     /
+ *  /                                               /
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                     QTYPE                     |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                     QCLASS                    |
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *
+ * The query name is encoded as a series of labels, each represented
+ * as a one-byte length (maximum 63) followed by the text of the
+ * label.  The list is terminated by a label of length zero (which can
+ * be thought of as the root domain).
+ */
+
+int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
+                 int rd, unsigned char **buf, int *buflen)
+{
+  int len;
+  unsigned char *q;
+  const char *p;
+
+  /* Set our results early, in case we bail out early with an error. */
+  *buflen = 0;
+  *buf = NULL;
+
+  /* Compute the length of the encoded name so we can check buflen.
+   * Start counting at 1 for the zero-length label at the end. */
+  len = 1;
+  for (p = name; *p; p++)
+    {
+      if (*p == '\\' && *(p + 1) != 0)
+        p++;
+      len++;
+    }
+  /* If there are n periods in the name, there are n + 1 labels, and
+   * thus n + 1 length fields, unless the name is empty or ends with a
+   * period.  So add 1 unless name is empty or ends with a period.
+   */
+  if (*name && *(p - 1) != '.')
+    len++;
+
+  /* Immediately reject names that are longer than the maximum of 255
+   * bytes that's specified in RFC 1035 ("To simplify implementations,
+   * the total length of a domain name (i.e., label octets and label
+   * length octets) is restricted to 255 octets or less."). We aren't
+   * doing this just to be a stickler about RFCs. For names that are
+   * too long, 'dnscache' closes its TCP connection to us immediately
+   * (when using TCP) and ignores the request when using UDP, and
+   * BIND's named returns ServFail (TCP or UDP). Sending a request
+   * that we know will cause 'dnscache' to close the TCP connection is
+   * painful, since that makes any other outstanding requests on that
+   * connection fail. And sending a UDP request that we know
+   * 'dnscache' will ignore is bad because resources will be tied up
+   * until we time-out the request.
+   */
+  if (len > MAXCDNAME)
+    return ARES_EBADNAME;
+
+  *buflen = len + HFIXEDSZ + QFIXEDSZ;
+  *buf = malloc(*buflen);
+  if (!*buf)
+      return ARES_ENOMEM;
+
+  /* Set up the header. */
+  q = *buf;
+  memset(q, 0, HFIXEDSZ);
+  DNS_HEADER_SET_QID(q, id);
+  DNS_HEADER_SET_OPCODE(q, QUERY);
+  if (rd) {
+    DNS_HEADER_SET_RD(q, 1);
+  }
+  else {
+    DNS_HEADER_SET_RD(q, 0);
+  }
+  DNS_HEADER_SET_QDCOUNT(q, 1);
+
+  /* A name of "." is a screw case for the loop below, so adjust it. */
+  if (strcmp(name, ".") == 0)
+    name++;
+
+  /* Start writing out the name after the header. */
+  q += HFIXEDSZ;
+  while (*name)
+    {
+      if (*name == '.')
+        return ARES_EBADNAME;
+
+      /* Count the number of bytes in this label. */
+      len = 0;
+      for (p = name; *p && *p != '.'; p++)
+        {
+          if (*p == '\\' && *(p + 1) != 0)
+            p++;
+          len++;
+        }
+      if (len > MAXLABEL)
+        return ARES_EBADNAME;
+
+      /* Encode the length and copy the data. */
+      *q++ = (unsigned char)len;
+      for (p = name; *p && *p != '.'; p++)
+        {
+          if (*p == '\\' && *(p + 1) != 0)
+            p++;
+          *q++ = *p;
+        }
+
+      /* Go to the next label and repeat, unless we hit the end. */
+      if (!*p)
+        break;
+      name = p + 1;
+    }
+
+  /* Add the zero-length label at the end. */
+  *q++ = 0;
+
+  /* Finish off the question with the type and class. */
+  DNS_QUESTION_SET_TYPE(q, type);
+  DNS_QUESTION_SET_CLASS(q, dnsclass);
+
+  return ARES_SUCCESS;
+}
diff --git a/3rdParty/CAres/src/ares_parse_a_reply.c b/3rdParty/CAres/src/ares_parse_a_reply.c
new file mode 100644
index 0000000..801c193
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_a_reply.c
@@ -0,0 +1,257 @@
+/* $Id: ares_parse_a_reply.c,v 1.20 2009-11-23 01:24:17 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares_parse_a_reply(const unsigned char *abuf, int alen,
+                       struct hostent **host,
+                       struct ares_addrttl *addrttls, int *naddrttls)
+{
+  unsigned int qdcount, ancount;
+  int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
+  int cname_ttl = INT_MAX;  /* the TTL imposed by the CNAME chain */
+  int naliases;
+  long len;
+  const unsigned char *aptr;
+  char *hostname, *rr_name, *rr_data, **aliases;
+  struct in_addr *addrs;
+  struct hostent *hostent;
+  const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
+
+  /* Set *host to NULL for all failure cases. */
+  if (host)
+    *host = NULL;
+  /* Same with *naddrttls. */
+  if (naddrttls)
+    *naddrttls = 0;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if (alen < HFIXEDSZ)
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT(abuf);
+  ancount = DNS_HEADER_ANCOUNT(abuf);
+  if (qdcount != 1)
+    return ARES_EBADRESP;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
+  if (status != ARES_SUCCESS)
+    return status;
+  if (aptr + len + QFIXEDSZ > abuf + alen)
+    {
+      free(hostname);
+      return ARES_EBADRESP;
+    }
+  aptr += len + QFIXEDSZ;
+
+  if (host)
+    {
+      /* Allocate addresses and aliases; ancount gives an upper bound for
+         both. */
+      addrs = malloc(ancount * sizeof(struct in_addr));
+      if (!addrs)
+        {
+          free(hostname);
+          return ARES_ENOMEM;
+        }
+      aliases = malloc((ancount + 1) * sizeof(char *));
+      if (!aliases)
+        {
+          free(hostname);
+          free(addrs);
+          return ARES_ENOMEM;
+        }
+    }
+  else
+    {
+      addrs = NULL;
+      aliases = NULL;
+    }
+
+  naddrs = 0;
+  naliases = 0;
+
+  /* Examine each answer resource record (RR) in turn. */
+  for (i = 0; i < (int)ancount; i++)
+    {
+      /* Decode the RR up to the data field. */
+      status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+      if (status != ARES_SUCCESS)
+        break;
+      aptr += len;
+      if (aptr + RRFIXEDSZ > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+      rr_type = DNS_RR_TYPE(aptr);
+      rr_class = DNS_RR_CLASS(aptr);
+      rr_len = DNS_RR_LEN(aptr);
+      rr_ttl = DNS_RR_TTL(aptr);
+      aptr += RRFIXEDSZ;
+
+      if (rr_class == C_IN && rr_type == T_A
+          && rr_len == sizeof(struct in_addr)
+          && strcasecmp(rr_name, hostname) == 0)
+        {
+          if (addrs)
+            {
+              if (aptr + sizeof(struct in_addr) > abuf + alen)
+              {
+                status = ARES_EBADRESP;
+                break;
+              }
+              memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
+            }
+          if (naddrs < max_addr_ttls)
+            {
+              struct ares_addrttl * const at = &addrttls[naddrs];
+              if (aptr + sizeof(struct in_addr) > abuf + alen)
+              {
+                status = ARES_EBADRESP;
+                break;
+              }
+              memcpy(&at->ipaddr, aptr,  sizeof(struct in_addr));
+              at->ttl = rr_ttl;
+            }
+          naddrs++;
+          status = ARES_SUCCESS;
+        }
+
+      if (rr_class == C_IN && rr_type == T_CNAME)
+        {
+          /* Record the RR name as an alias. */
+          if (aliases)
+            aliases[naliases] = rr_name;
+          else
+            free(rr_name);
+          naliases++;
+
+          /* Decode the RR data and replace the hostname with it. */
+          status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+                                                  &len);
+          if (status != ARES_SUCCESS)
+            break;
+          free(hostname);
+          hostname = rr_data;
+
+          /* Take the min of the TTLs we see in the CNAME chain. */
+          if (cname_ttl > rr_ttl)
+            cname_ttl = rr_ttl;
+        }
+      else
+        free(rr_name);
+
+      aptr += rr_len;
+      if (aptr > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+    }
+
+  if (status == ARES_SUCCESS && naddrs == 0)
+    status = ARES_ENODATA;
+  if (status == ARES_SUCCESS)
+    {
+      /* We got our answer. */
+      if (naddrttls)
+        {
+          const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
+          for (i = 0; i < n; i++)
+            {
+              /* Ensure that each A TTL is no larger than the CNAME TTL. */
+              if (addrttls[i].ttl > cname_ttl)
+                addrttls[i].ttl = cname_ttl;
+            }
+          *naddrttls = n;
+        }
+      if (aliases)
+        aliases[naliases] = NULL;
+      if (host)
+        {
+          /* Allocate memory to build the host entry. */
+          hostent = malloc(sizeof(struct hostent));
+          if (hostent)
+            {
+              hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));
+              if (hostent->h_addr_list)
+                {
+                  /* Fill in the hostent and return successfully. */
+                  hostent->h_name = hostname;
+                  hostent->h_aliases = aliases;
+                  hostent->h_addrtype = AF_INET;
+                  hostent->h_length = sizeof(struct in_addr);
+                  for (i = 0; i < naddrs; i++)
+                    hostent->h_addr_list[i] = (char *) &addrs[i];
+                  hostent->h_addr_list[naddrs] = NULL;
+                  *host = hostent;
+                  return ARES_SUCCESS;
+                }
+              free(hostent);
+            }
+          status = ARES_ENOMEM;
+        }
+     }
+  if (aliases)
+    {
+      for (i = 0; i < naliases; i++)
+        free(aliases[i]);
+      free(aliases);
+    }
+  free(addrs);
+  free(hostname);
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares_parse_aaaa_reply.c b/3rdParty/CAres/src/ares_parse_aaaa_reply.c
new file mode 100644
index 0000000..c2329cc
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_aaaa_reply.c
@@ -0,0 +1,257 @@
+/* $Id: ares_parse_aaaa_reply.c,v 1.16 2009-11-23 01:24:17 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright 2005 Dominick Meglio
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "inet_net_pton.h"
+#include "ares_private.h"
+
+int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
+                          struct hostent **host, struct ares_addr6ttl *addrttls,
+                          int *naddrttls)
+{
+  unsigned int qdcount, ancount;
+  int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
+  int cname_ttl = INT_MAX;  /* the TTL imposed by the CNAME chain */
+  int naliases;
+  long len;
+  const unsigned char *aptr;
+  char *hostname, *rr_name, *rr_data, **aliases;
+  struct in6_addr *addrs;
+  struct hostent *hostent;
+  const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
+
+  /* Set *host to NULL for all failure cases. */
+  if (host)
+    *host = NULL;
+  /* Same with *naddrttls. */
+  if (naddrttls)
+    *naddrttls = 0;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if (alen < HFIXEDSZ)
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT(abuf);
+  ancount = DNS_HEADER_ANCOUNT(abuf);
+  if (qdcount != 1)
+    return ARES_EBADRESP;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
+  if (status != ARES_SUCCESS)
+    return status;
+  if (aptr + len + QFIXEDSZ > abuf + alen)
+    {
+      free(hostname);
+      return ARES_EBADRESP;
+    }
+  aptr += len + QFIXEDSZ;
+
+  /* Allocate addresses and aliases; ancount gives an upper bound for both. */
+  if (host)
+    {
+      addrs = malloc(ancount * sizeof(struct in6_addr));
+      if (!addrs)
+        {
+          free(hostname);
+          return ARES_ENOMEM;
+        }
+      aliases = malloc((ancount + 1) * sizeof(char *));
+      if (!aliases)
+        {
+          free(hostname);
+          free(addrs);
+          return ARES_ENOMEM;
+        }
+    }
+  else
+    {
+      addrs = NULL;
+      aliases = NULL;
+    }
+  naddrs = 0;
+  naliases = 0;
+
+  /* Examine each answer resource record (RR) in turn. */
+  for (i = 0; i < (int)ancount; i++)
+    {
+      /* Decode the RR up to the data field. */
+      status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+      if (status != ARES_SUCCESS)
+        break;
+      aptr += len;
+      if (aptr + RRFIXEDSZ > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+      rr_type = DNS_RR_TYPE(aptr);
+      rr_class = DNS_RR_CLASS(aptr);
+      rr_len = DNS_RR_LEN(aptr);
+      rr_ttl = DNS_RR_TTL(aptr);
+      aptr += RRFIXEDSZ;
+
+      if (rr_class == C_IN && rr_type == T_AAAA
+          && rr_len == sizeof(struct in6_addr)
+          && strcasecmp(rr_name, hostname) == 0)
+        {
+          if (addrs)
+            {
+              if (aptr + sizeof(struct in6_addr) > abuf + alen)
+              {
+                status = ARES_EBADRESP;
+                break;
+              }
+              memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr));
+            }
+          if (naddrs < max_addr_ttls)
+            {
+              struct ares_addr6ttl * const at = &addrttls[naddrs];
+              if (aptr + sizeof(struct in6_addr) > abuf + alen)
+              {
+                status = ARES_EBADRESP;
+                break;
+              }
+              memcpy(&at->ip6addr, aptr,  sizeof(struct in6_addr));
+              at->ttl = rr_ttl;
+            }
+          naddrs++;
+          status = ARES_SUCCESS;
+        }
+
+      if (rr_class == C_IN && rr_type == T_CNAME)
+        {
+          /* Record the RR name as an alias. */
+          if (aliases)
+            aliases[naliases] = rr_name;
+          else
+            free(rr_name);
+          naliases++;
+
+          /* Decode the RR data and replace the hostname with it. */
+          status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+                                                  &len);
+          if (status != ARES_SUCCESS)
+            break;
+          free(hostname);
+          hostname = rr_data;
+
+          /* Take the min of the TTLs we see in the CNAME chain. */
+          if (cname_ttl > rr_ttl)
+            cname_ttl = rr_ttl;
+        }
+      else
+        free(rr_name);
+
+      aptr += rr_len;
+      if (aptr > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+    }
+
+  if (status == ARES_SUCCESS && naddrs == 0)
+    status = ARES_ENODATA;
+  if (status == ARES_SUCCESS)
+    {
+      /* We got our answer. */
+      if (naddrttls)
+        {
+          const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
+          for (i = 0; i < n; i++)
+            {
+              /* Ensure that each A TTL is no larger than the CNAME TTL. */
+              if (addrttls[i].ttl > cname_ttl)
+                addrttls[i].ttl = cname_ttl;
+            }
+          *naddrttls = n;
+        }
+      if (aliases)
+        aliases[naliases] = NULL;
+      if (host)
+        {
+          /* Allocate memory to build the host entry. */
+          hostent = malloc(sizeof(struct hostent));
+          if (hostent)
+            {
+              hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));
+              if (hostent->h_addr_list)
+                {
+                  /* Fill in the hostent and return successfully. */
+                  hostent->h_name = hostname;
+                  hostent->h_aliases = aliases;
+                  hostent->h_addrtype = AF_INET6;
+                  hostent->h_length = sizeof(struct in6_addr);
+                  for (i = 0; i < naddrs; i++)
+                    hostent->h_addr_list[i] = (char *) &addrs[i];
+                  hostent->h_addr_list[naddrs] = NULL;
+                  *host = hostent;
+                  return ARES_SUCCESS;
+                }
+              free(hostent);
+            }
+          status = ARES_ENOMEM;
+        }
+    }
+  if (aliases)
+    {
+      for (i = 0; i < naliases; i++)
+        free(aliases[i]);
+      free(aliases);
+    }
+  free(addrs);
+  free(hostname);
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares_parse_ns_reply.c b/3rdParty/CAres/src/ares_parse_ns_reply.c
new file mode 100644
index 0000000..25c6329
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_ns_reply.c
@@ -0,0 +1,182 @@
+/* $Id */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/*
+ * ares_parse_ns_reply created by Vlad Dinulescu <vlad.dinulescu@avira.com>
+ *      on behalf of AVIRA Gmbh - http://www.avira.com
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares_parse_ns_reply( const unsigned char* abuf, int alen,
+                         struct hostent** host )
+{
+  unsigned int qdcount, ancount;
+  int status, i, rr_type, rr_class, rr_len;
+  int nameservers_num;
+  long len;
+  const unsigned char *aptr;
+  char* hostname, *rr_name, *rr_data, **nameservers;
+  struct hostent *hostent;
+
+  /* Set *host to NULL for all failure cases. */
+  *host = NULL;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if ( alen < HFIXEDSZ )
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT( abuf );
+  ancount = DNS_HEADER_ANCOUNT( abuf );
+  if ( qdcount != 1 )
+    return ARES_EBADRESP;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len);
+  if ( status != ARES_SUCCESS )
+    return status;
+  if ( aptr + len + QFIXEDSZ > abuf + alen )
+  {
+    free( hostname );
+    return ARES_EBADRESP;
+  }
+  aptr += len + QFIXEDSZ;
+
+  /* Allocate nameservers array; ancount gives an upper bound */
+  nameservers = malloc( ( ancount + 1 ) * sizeof( char * ) );
+  if ( !nameservers )
+  {
+    free( hostname );
+    return ARES_ENOMEM;
+  }
+  nameservers_num = 0;
+
+  /* Examine each answer resource record (RR) in turn. */
+  for ( i = 0; i < ( int ) ancount; i++ )
+  {
+    /* Decode the RR up to the data field. */
+    status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len );
+    if ( status != ARES_SUCCESS )
+      break;
+    aptr += len;
+    if ( aptr + RRFIXEDSZ > abuf + alen )
+    {
+      status = ARES_EBADRESP;
+      break;
+    }
+    rr_type = DNS_RR_TYPE( aptr );
+    rr_class = DNS_RR_CLASS( aptr );
+    rr_len = DNS_RR_LEN( aptr );
+    aptr += RRFIXEDSZ;
+
+    if ( rr_class == C_IN && rr_type == T_NS )
+    {
+      /* Decode the RR data and add it to the nameservers list */
+      status = ares__expand_name_for_response( aptr, abuf, alen, &rr_data,
+                                               &len);
+      if ( status != ARES_SUCCESS )
+      {
+        break;
+      }
+
+      nameservers[nameservers_num] = malloc(strlen(rr_data)+1);
+
+      if (nameservers[nameservers_num]==NULL)
+      {
+        free(rr_name);
+        free(rr_data);
+        status=ARES_ENOMEM;
+        break;
+      }
+      strcpy(nameservers[nameservers_num],rr_data);
+      free(rr_data);
+
+      nameservers_num++;
+    }
+
+    free( rr_name );
+
+    aptr += rr_len;
+    if ( aptr > abuf + alen )
+    {
+      status = ARES_EBADRESP;
+      break;
+    }
+  }
+
+  if ( status == ARES_SUCCESS && nameservers_num == 0 )
+  {
+    status = ARES_ENODATA;
+  }
+  if ( status == ARES_SUCCESS )
+  {
+    /* We got our answer.  Allocate memory to build the host entry. */
+    nameservers[nameservers_num] = NULL;
+    hostent = malloc( sizeof( struct hostent ) );
+    if ( hostent )
+    {
+      hostent->h_addr_list = malloc( 1 * sizeof( char * ) );
+      if ( hostent->h_addr_list )
+      {
+        /* Fill in the hostent and return successfully. */
+        hostent->h_name = hostname;
+        hostent->h_aliases = nameservers;
+        hostent->h_addrtype = AF_INET;
+        hostent->h_length = sizeof( struct in_addr );
+        hostent->h_addr_list[0] = NULL;
+        *host = hostent;
+        return ARES_SUCCESS;
+      }
+      free( hostent );
+    }
+    status = ARES_ENOMEM;
+  }
+  for ( i = 0; i < nameservers_num; i++ )
+    free( nameservers[i] );
+  free( nameservers );
+  free( hostname );
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares_parse_ptr_reply.c b/3rdParty/CAres/src/ares_parse_ptr_reply.c
new file mode 100644
index 0000000..6f039b9
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_ptr_reply.c
@@ -0,0 +1,209 @@
+/* $Id: ares_parse_ptr_reply.c,v 1.21 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
+                         int addrlen, int family, struct hostent **host)
+{
+  unsigned int qdcount, ancount;
+  int status, i, rr_type, rr_class, rr_len;
+  long len;
+  const unsigned char *aptr;
+  char *ptrname, *hostname, *rr_name, *rr_data;
+  struct hostent *hostent;
+  int aliascnt = 0;
+  int alias_alloc = 8;
+  char ** aliases;
+
+  /* Set *host to NULL for all failure cases. */
+  *host = NULL;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if (alen < HFIXEDSZ)
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT(abuf);
+  ancount = DNS_HEADER_ANCOUNT(abuf);
+  if (qdcount != 1)
+    return ARES_EBADRESP;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
+  if (status != ARES_SUCCESS)
+    return status;
+  if (aptr + len + QFIXEDSZ > abuf + alen)
+    {
+      free(ptrname);
+      return ARES_EBADRESP;
+    }
+  aptr += len + QFIXEDSZ;
+
+  /* Examine each answer resource record (RR) in turn. */
+  hostname = NULL;
+  aliases = malloc(alias_alloc * sizeof(char *));
+  if (!aliases)
+    {
+      free(ptrname);
+      return ARES_ENOMEM;
+    }
+  for (i = 0; i < (int)ancount; i++)
+    {
+      /* Decode the RR up to the data field. */
+      status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+      if (status != ARES_SUCCESS)
+        break;
+      aptr += len;
+      if (aptr + RRFIXEDSZ > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+      rr_type = DNS_RR_TYPE(aptr);
+      rr_class = DNS_RR_CLASS(aptr);
+      rr_len = DNS_RR_LEN(aptr);
+      aptr += RRFIXEDSZ;
+
+      if (rr_class == C_IN && rr_type == T_PTR
+          && strcasecmp(rr_name, ptrname) == 0)
+        {
+          /* Decode the RR data and set hostname to it. */
+          status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+                                                  &len);
+          if (status != ARES_SUCCESS)
+            break;
+          if (hostname)
+            free(hostname);
+          hostname = rr_data;
+          aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char *));
+          if (!aliases[aliascnt])
+            {
+              status = ARES_ENOMEM;
+              break;
+            }
+          strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
+          aliascnt++;
+          if (aliascnt >= alias_alloc) {
+            char **ptr;
+            alias_alloc *= 2;
+            ptr = realloc(aliases, alias_alloc * sizeof(char *));
+            if(!ptr) {
+              status = ARES_ENOMEM;
+              break;
+            }
+            aliases = ptr;
+          }
+        }
+
+      if (rr_class == C_IN && rr_type == T_CNAME)
+        {
+          /* Decode the RR data and replace ptrname with it. */
+          status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+                                                  &len);
+          if (status != ARES_SUCCESS)
+            break;
+          free(ptrname);
+          ptrname = rr_data;
+        }
+
+      free(rr_name);
+      aptr += rr_len;
+      if (aptr > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+    }
+
+  if (status == ARES_SUCCESS && !hostname)
+    status = ARES_ENODATA;
+  if (status == ARES_SUCCESS)
+    {
+      /* We got our answer.  Allocate memory to build the host entry. */
+      hostent = malloc(sizeof(struct hostent));
+      if (hostent)
+        {
+          hostent->h_addr_list = malloc(2 * sizeof(char *));
+          if (hostent->h_addr_list)
+            {
+              hostent->h_addr_list[0] = malloc(addrlen);
+              if (hostent->h_addr_list[0])
+                {
+                  hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *));
+                  if (hostent->h_aliases)
+                    {
+                      /* Fill in the hostent and return successfully. */
+                      hostent->h_name = hostname;
+                      for (i=0 ; i<aliascnt ; i++)
+                        hostent->h_aliases[i] = aliases[i];
+                      hostent->h_aliases[aliascnt] = NULL;
+                      hostent->h_addrtype = family;
+                      hostent->h_length = addrlen;
+                      memcpy(hostent->h_addr_list[0], addr, addrlen);
+                      hostent->h_addr_list[1] = NULL;
+                      *host = hostent;
+                      free(aliases);
+                      free(ptrname);
+                      return ARES_SUCCESS;
+                    }
+                  free(hostent->h_addr_list[0]);
+                }
+              free(hostent->h_addr_list);
+            }
+          free(hostent);
+        }
+      status = ARES_ENOMEM;
+    }
+  for (i=0 ; i<aliascnt ; i++)
+    if (aliases[i]) 
+      free(aliases[i]);
+  free(aliases);
+  if (hostname)
+    free(hostname);
+  free(ptrname);
+  return status;
+}
diff --git a/3rdParty/CAres/src/ares_parse_srv_reply.c b/3rdParty/CAres/src/ares_parse_srv_reply.c
new file mode 100644
index 0000000..72830af
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_srv_reply.c
@@ -0,0 +1,180 @@
+/* $Id: ares_parse_srv_reply.c,v 1.12 2009-11-26 01:21:21 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2009 by Jakub Hrozek <jhrozek@redhat.com>
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+/* AIX portability check */
+#ifndef T_SRV
+#  define T_SRV 33 /* server selection */
+#endif
+
+int
+ares_parse_srv_reply (const unsigned char *abuf, int alen,
+                      struct ares_srv_reply **srv_out)
+{
+  unsigned int qdcount, ancount, i;
+  const unsigned char *aptr, *vptr;
+  int status, rr_type, rr_class, rr_len;
+  long len;
+  char *hostname = NULL, *rr_name = NULL;
+  struct ares_srv_reply *srv_head = NULL;
+  struct ares_srv_reply *srv_last = NULL;
+  struct ares_srv_reply *srv_curr;
+
+  /* Set *srv_out to NULL for all failure cases. */
+  *srv_out = NULL;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if (alen < HFIXEDSZ)
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT (abuf);
+  ancount = DNS_HEADER_ANCOUNT (abuf);
+  if (qdcount != 1)
+    return ARES_EBADRESP;
+  if (ancount == 0)
+    return ARES_ENODATA;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
+  if (status != ARES_SUCCESS)
+    return status;
+
+  if (aptr + len + QFIXEDSZ > abuf + alen)
+    {
+      free (hostname);
+      return ARES_EBADRESP;
+    }
+  aptr += len + QFIXEDSZ;
+
+  /* Examine each answer resource record (RR) in turn. */
+  for (i = 0; i < ancount; i++)
+    {
+      /* Decode the RR up to the data field. */
+      status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
+      if (status != ARES_SUCCESS)
+        {
+          break;
+        }
+      aptr += len;
+      if (aptr + RRFIXEDSZ > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+      rr_type = DNS_RR_TYPE (aptr);
+      rr_class = DNS_RR_CLASS (aptr);
+      rr_len = DNS_RR_LEN (aptr);
+      aptr += RRFIXEDSZ;
+
+      /* Check if we are really looking at a SRV record */
+      if (rr_class == C_IN && rr_type == T_SRV)
+        {
+          /* parse the SRV record itself */
+          if (rr_len < 6)
+            {
+              status = ARES_EBADRESP;
+              break;
+            }
+
+          /* Allocate storage for this SRV answer appending it to the list */
+          srv_curr = ares_malloc_data(ARES_DATATYPE_SRV_REPLY);
+          if (!srv_curr)
+            {
+              status = ARES_ENOMEM;
+              break;
+            }
+          if (srv_last)
+            {
+              srv_last->next = srv_curr;
+            }
+          else
+            {
+              srv_head = srv_curr;
+            }
+          srv_last = srv_curr;
+
+          vptr = aptr;
+          srv_curr->priority = ntohs (*((unsigned short *)vptr));
+          vptr += sizeof(unsigned short);
+          srv_curr->weight = ntohs (*((unsigned short *)vptr));
+          vptr += sizeof(unsigned short);
+          srv_curr->port = ntohs (*((unsigned short *)vptr));
+          vptr += sizeof(unsigned short);
+
+          status = ares_expand_name (vptr, abuf, alen, &srv_curr->host, &len);
+          if (status != ARES_SUCCESS)
+            break;
+        }
+
+      /* Don't lose memory in the next iteration */
+      free (rr_name);
+      rr_name = NULL;
+
+      /* Move on to the next record */
+      aptr += rr_len;
+    }
+
+  if (hostname)
+    free (hostname);
+  if (rr_name)
+    free (rr_name);
+
+  /* clean up on error */
+  if (status != ARES_SUCCESS)
+    {
+      if (srv_head)
+        ares_free_data (srv_head);
+      return status;
+    }
+
+  /* everything looks fine, return the data */
+  *srv_out = srv_head;
+
+  return ARES_SUCCESS;
+}
diff --git a/3rdParty/CAres/src/ares_parse_txt_reply.c b/3rdParty/CAres/src/ares_parse_txt_reply.c
new file mode 100644
index 0000000..b6af850
--- /dev/null
+++ b/3rdParty/CAres/src/ares_parse_txt_reply.c
@@ -0,0 +1,202 @@
+/* $Id: ares_parse_txt_reply.c,v 1.9 2009-11-26 01:21:21 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2009 by Jakub Hrozek <jhrozek@redhat.com>
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+int
+ares_parse_txt_reply (const unsigned char *abuf, int alen,
+                      struct ares_txt_reply **txt_out)
+{
+  size_t substr_len, str_len;
+  unsigned int qdcount, ancount, i;
+  const unsigned char *aptr;
+  const unsigned char *strptr;
+  int status, rr_type, rr_class, rr_len;
+  long len;
+  char *hostname = NULL, *rr_name = NULL;
+  struct ares_txt_reply *txt_head = NULL;
+  struct ares_txt_reply *txt_last = NULL;
+  struct ares_txt_reply *txt_curr;
+
+  /* Set *txt_out to NULL for all failure cases. */
+  *txt_out = NULL;
+
+  /* Give up if abuf doesn't have room for a header. */
+  if (alen < HFIXEDSZ)
+    return ARES_EBADRESP;
+
+  /* Fetch the question and answer count from the header. */
+  qdcount = DNS_HEADER_QDCOUNT (abuf);
+  ancount = DNS_HEADER_ANCOUNT (abuf);
+  if (qdcount != 1)
+    return ARES_EBADRESP;
+  if (ancount == 0)
+    return ARES_ENODATA;
+
+  /* Expand the name from the question, and skip past the question. */
+  aptr = abuf + HFIXEDSZ;
+  status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
+  if (status != ARES_SUCCESS)
+    return status;
+
+  if (aptr + len + QFIXEDSZ > abuf + alen)
+    {
+      free (hostname);
+      return ARES_EBADRESP;
+    }
+  aptr += len + QFIXEDSZ;
+
+  /* Examine each answer resource record (RR) in turn. */
+  for (i = 0; i < ancount; i++)
+    {
+      /* Decode the RR up to the data field. */
+      status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
+      if (status != ARES_SUCCESS)
+        {
+          break;
+        }
+      aptr += len;
+      if (aptr + RRFIXEDSZ > abuf + alen)
+        {
+          status = ARES_EBADRESP;
+          break;
+        }
+      rr_type = DNS_RR_TYPE (aptr);
+      rr_class = DNS_RR_CLASS (aptr);
+      rr_len = DNS_RR_LEN (aptr);
+      aptr += RRFIXEDSZ;
+
+      /* Check if we are really looking at a TXT record */
+      if (rr_class == C_IN && rr_type == T_TXT)
+        {
+          /* Allocate storage for this TXT answer appending it to the list */
+          txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
+          if (!txt_curr)
+            {
+              status = ARES_ENOMEM;
+              break;
+            }
+          if (txt_last)
+            {
+              txt_last->next = txt_curr;
+            }
+          else
+            {
+              txt_head = txt_curr;
+            }
+          txt_last = txt_curr;
+
+          /*
+           * There may be multiple substrings in a single TXT record. Each
+           * substring may be up to 255 characters in length, with a
+           * "length byte" indicating the size of the substring payload.
+           * RDATA contains both the length-bytes and payloads of all
+           * substrings contained therein.
+           */
+
+          /* Compute total length to allow a single memory allocation */
+          strptr = aptr;
+          while (strptr < (aptr + rr_len))
+            {
+              substr_len = (unsigned char)*strptr;
+              txt_curr->length += substr_len;
+              strptr += substr_len + 1;
+            }
+
+          /* Including null byte */
+          txt_curr->txt = malloc (txt_curr->length + 1);
+          if (txt_curr->txt == NULL)
+            {
+              status = ARES_ENOMEM;
+              break;
+            }
+
+          /* Step through the list of substrings, concatenating them */
+          str_len = 0;
+          strptr = aptr;
+          while (strptr < (aptr + rr_len))
+            {
+              substr_len = (unsigned char)*strptr;
+              strptr++;
+              memcpy ((char *) txt_curr->txt + str_len, strptr, substr_len);
+              str_len += substr_len;
+              strptr += substr_len;
+            }
+          /* Make sure we NULL-terminate */
+          *((char *) txt_curr->txt + txt_curr->length) = '\0';
+        }
+
+      /* Don't lose memory in the next iteration */
+      free (rr_name);
+      rr_name = NULL;
+
+      /* Move on to the next record */
+      aptr += rr_len;
+    }
+
+  if (hostname)
+    free (hostname);
+  if (rr_name)
+    free (rr_name);
+
+  /* clean up on error */
+  if (status != ARES_SUCCESS)
+    {
+      if (txt_head)
+        ares_free_data (txt_head);
+      return status;
+    }
+
+  /* everything looks fine, return the data */
+  *txt_out = txt_head;
+
+  return ARES_SUCCESS;
+}
diff --git a/3rdParty/CAres/src/ares_private.h b/3rdParty/CAres/src/ares_private.h
new file mode 100644
index 0000000..4726d7a
--- /dev/null
+++ b/3rdParty/CAres/src/ares_private.h
@@ -0,0 +1,343 @@
+#ifndef __ARES_PRIVATE_H
+#define __ARES_PRIVATE_H
+
+/* $Id: ares_private.h,v 1.50 2009-11-09 12:56:50 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef WATT32
+#include <tcp.h>
+#include <sys/ioctl.h>
+#define writev(s,v,c)     writev_s(s,v,c)
+#define HAVE_WRITEV 1
+#endif
+
+#ifdef NETWARE
+#include <time.h>
+#endif
+
+#define DEFAULT_TIMEOUT         5000 /* milliseconds */
+#define DEFAULT_TRIES           4
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+#if defined(WIN32) && !defined(WATT32)
+
+#define IS_NT()        ((int)GetVersion() > 0)
+#define WIN_NS_9X      "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
+#define WIN_NS_NT_KEY  "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define NAMESERVER     "NameServer"
+#define DHCPNAMESERVER "DhcpNameServer"
+#define DATABASEPATH   "DatabasePath"
+#define WIN_PATH_HOSTS  "\\hosts"
+
+#elif defined(WATT32)
+
+#define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf"
+
+#elif defined(NETWARE)
+
+#define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
+#define PATH_HOSTS              "sys:/etc/hosts"
+
+#elif defined(__riscos__)
+
+#define PATH_HOSTS             "InetDBase:Hosts"
+
+#else
+
+#define PATH_RESOLV_CONF        "/etc/resolv.conf"
+#ifdef ETC_INET
+#define PATH_HOSTS              "/etc/inet/hosts"
+#else
+#define PATH_HOSTS              "/etc/hosts"
+#endif
+
+#endif
+
+#define ARES_ID_KEY_LEN 31
+
+#include "ares_ipv6.h"
+#include "ares_llist.h"
+
+#ifndef HAVE_STRDUP
+#  include "ares_strdup.h"
+#  define strdup(ptr) ares_strdup(ptr)
+#endif
+
+#ifndef HAVE_STRCASECMP
+#  include "ares_strcasecmp.h"
+#  define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
+#endif
+
+#ifndef HAVE_STRNCASECMP
+#  include "ares_strcasecmp.h"
+#  define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
+#endif
+
+#ifndef HAVE_WRITEV
+#  include "ares_writev.h"
+#  define writev(s,ptr,cnt) ares_writev(s,ptr,cnt)
+#endif
+
+struct ares_addr {
+  int family;
+  union {
+    struct in_addr  addr4;
+    struct in6_addr addr6;
+  } addr;
+};
+#define addrV4 addr.addr4
+#define addrV6 addr.addr6
+
+struct query;
+
+struct send_request {
+  /* Remaining data to send */
+  const unsigned char *data;
+  size_t len;
+
+  /* The query for which we're sending this data */
+  struct query* owner_query;
+  /* The buffer we're using, if we have our own copy of the packet */
+  unsigned char *data_storage;
+
+  /* Next request in queue */
+  struct send_request *next;
+};
+
+struct server_state {
+  struct in_addr addr;
+  ares_socket_t udp_socket;
+  ares_socket_t tcp_socket;
+
+  /* Mini-buffer for reading the length word */
+  unsigned char tcp_lenbuf[2];
+  int tcp_lenbuf_pos;
+  int tcp_length;
+
+  /* Buffer for reading actual TCP data */
+  unsigned char *tcp_buffer;
+  int tcp_buffer_pos;
+
+  /* TCP output queue */
+  struct send_request *qhead;
+  struct send_request *qtail;
+
+  /* Which incarnation of this connection is this? We don't want to
+   * retransmit requests into the very same socket, but if the server
+   * closes on us and we re-open the connection, then we do want to
+   * re-send. */
+  int tcp_connection_generation;
+
+  /* Circular, doubly-linked list of outstanding queries to this server */
+  struct list_node queries_to_server;
+
+  /* Link back to owning channel */
+  ares_channel channel;
+
+  /* Is this server broken? We mark connections as broken when a
+   * request that is queued for sending times out.
+   */
+  int is_broken;
+};
+
+/* State to represent a DNS query */
+struct query {
+  /* Query ID from qbuf, for faster lookup, and current timeout */
+  unsigned short qid;
+  struct timeval timeout;
+
+  /*
+   * Links for the doubly-linked lists in which we insert a query.
+   * These circular, doubly-linked lists that are hash-bucketed based
+   * the attributes we care about, help making most important
+   * operations O(1).
+   */
+  struct list_node queries_by_qid;    /* hopefully in same cache line as qid */
+  struct list_node queries_by_timeout;
+  struct list_node queries_to_server;
+  struct list_node all_queries;
+
+  /* Query buf with length at beginning, for TCP transmission */
+  unsigned char *tcpbuf;
+  int tcplen;
+
+  /* Arguments passed to ares_send() (qbuf points into tcpbuf) */
+  const unsigned char *qbuf;
+  int qlen;
+  ares_callback callback;
+  void *arg;
+
+  /* Query status */
+  int try; /* Number of times we tried this query already. */
+  int server; /* Server this query has last been sent to. */
+  struct query_server_info *server_info;   /* per-server state */
+  int using_tcp;
+  int error_status;
+  int timeouts; /* number of timeouts we saw for this request */
+};
+
+/* Per-server state for a query */
+struct query_server_info {
+  int skip_server;  /* should we skip server, due to errors, etc? */
+  int tcp_connection_generation;  /* into which TCP connection did we send? */
+};
+
+/* An IP address pattern; matches an IP address X if X & mask == addr */
+#define PATTERN_MASK 0x1
+#define PATTERN_CIDR 0x2
+
+struct apattern {
+  union
+  {
+    struct in_addr  addr4;
+    struct in6_addr addr6;
+  } addr;
+  union
+  {
+    struct in_addr  addr4;
+    struct in6_addr addr6;
+    unsigned short  bits;
+  } mask;
+  int family;
+  unsigned short type;
+};
+
+typedef struct rc4_key
+{
+  unsigned char state[256];
+  unsigned char x;
+  unsigned char y;
+} rc4_key;
+
+struct ares_channeldata {
+  /* Configuration data */
+  int flags;
+  int timeout; /* in milliseconds */
+  int tries;
+  int ndots;
+  int rotate; /* if true, all servers specified are used */
+  int udp_port;
+  int tcp_port;
+  int socket_send_buffer_size;
+  int socket_receive_buffer_size;
+  char **domains;
+  int ndomains;
+  struct apattern *sortlist;
+  int nsort;
+  char *lookups;
+
+  int optmask; /* the option bitfield passed in at init time */
+
+  /* Server addresses and communications state */
+  struct server_state *servers;
+  int nservers;
+
+  /* ID to use for next query */
+  unsigned short next_id;
+  /* key to use when generating new ids */
+  rc4_key id_key;
+
+  /* Generation number to use for the next TCP socket open/close */
+  int tcp_connection_generation;
+
+  /* The time at which we last called process_timeouts(). Uses integer seconds
+     just to draw the line somewhere. */
+  time_t last_timeout_processed;
+
+  /* Last server we sent a query to. */
+  int last_server;
+
+  /* Circular, doubly-linked list of queries, bucketed various ways.... */
+  /* All active queries in a single list: */
+  struct list_node all_queries;
+  /* Queries bucketed by qid, for quickly dispatching DNS responses: */
+#define ARES_QID_TABLE_SIZE 2048
+  struct list_node queries_by_qid[ARES_QID_TABLE_SIZE];
+  /* Queries bucketed by timeout, for quickly handling timeouts: */
+#define ARES_TIMEOUT_TABLE_SIZE 1024
+  struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE];
+
+  ares_sock_state_cb sock_state_cb;
+  void *sock_state_cb_data;
+
+  ares_sock_create_callback sock_create_cb;
+  void *sock_create_cb_data;
+};
+
+/* return true if now is exactly check time or later */
+int ares__timedout(struct timeval *now,
+                   struct timeval *check);
+/* add the specific number of milliseconds to the time in the first argument */
+int ares__timeadd(struct timeval *now,
+                  int millisecs);
+/* return time offset between now and (future) check, in milliseconds */
+long ares__timeoffset(struct timeval *now,
+                      struct timeval *check);
+/* returns ARES_SUCCESS if library has been initialized */
+int ares_library_initialized(void);
+void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len);
+void ares__send_query(ares_channel channel, struct query *query,
+                      struct timeval *now);
+void ares__close_sockets(ares_channel channel, struct server_state *server);
+int ares__get_hostent(FILE *fp, int family, struct hostent **host);
+int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
+void ares__free_query(struct query *query);
+unsigned short ares__generate_new_id(rc4_key* key);
+struct timeval ares__tvnow(void);
+int ares__expand_name_for_response(const unsigned char *encoded,
+                                   const unsigned char *abuf, int alen,
+                                   char **s, long *enclen);
+#if 0 /* Not used */
+long ares__tvdiff(struct timeval t1, struct timeval t2);
+#endif
+
+#define ARES_SWAP_BYTE(a,b) \
+  { unsigned char swapByte = *(a);  *(a) = *(b);  *(b) = swapByte; }
+
+#define SOCK_STATE_CALLBACK(c, s, r, w)                                 \
+  do {                                                                  \
+    if ((c)->sock_state_cb)                                             \
+      (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w));       \
+  } while (0)
+
+#ifdef CURLDEBUG
+/* This is low-level hard-hacking memory leak tracking and similar. Using the
+   libcurl lowlevel code from within library is ugly and only works when
+   c-ares is built and linked with a similarly curldebug-enabled libcurl,
+   but we do this anyway for convenience. */
+#include "../lib/memdebug.h"
+#endif
+
+#endif /* __ARES_PRIVATE_H */
diff --git a/3rdParty/CAres/src/ares_process.c b/3rdParty/CAres/src/ares_process.c
new file mode 100644
index 0000000..6182ccc
--- /dev/null
+++ b/3rdParty/CAres/src/ares_process.c
@@ -0,0 +1,1170 @@
+/* $Id: ares_process.c,v 1.79 2009-11-18 10:33:54 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004-2009 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include <sys/uio.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#  include <netinet/tcp.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#  include <sys/ioctl.h>
+#endif
+#ifdef NETWARE
+#  include <sys/filio.h>
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+
+static int try_again(int errnum);
+static void write_tcp_data(ares_channel channel, fd_set *write_fds,
+                           ares_socket_t write_fd, struct timeval *now);
+static void read_tcp_data(ares_channel channel, fd_set *read_fds,
+                          ares_socket_t read_fd, struct timeval *now);
+static void read_udp_packets(ares_channel channel, fd_set *read_fds,
+                             ares_socket_t read_fd, struct timeval *now);
+static void advance_tcp_send_queue(ares_channel channel, int whichserver,
+                                   ssize_t num_bytes);
+static void process_timeouts(ares_channel channel, struct timeval *now);
+static void process_broken_connections(ares_channel channel,
+                                       struct timeval *now);
+static void process_answer(ares_channel channel, unsigned char *abuf,
+                           int alen, int whichserver, int tcp,
+                           struct timeval *now);
+static void handle_error(ares_channel channel, int whichserver,
+                         struct timeval *now);
+static void skip_server(ares_channel channel, struct query *query,
+                        int whichserver);
+static void next_server(ares_channel channel, struct query *query,
+                        struct timeval *now);
+static int configure_socket(int s, ares_channel channel);
+static int open_tcp_socket(ares_channel channel, struct server_state *server);
+static int open_udp_socket(ares_channel channel, struct server_state *server);
+static int same_questions(const unsigned char *qbuf, int qlen,
+                          const unsigned char *abuf, int alen);
+static void end_query(ares_channel channel, struct query *query, int status,
+                      unsigned char *abuf, int alen);
+
+/* return true if now is exactly check time or later */
+int ares__timedout(struct timeval *now,
+                   struct timeval *check)
+{
+  long secs = (now->tv_sec - check->tv_sec);
+
+  if(secs > 0)
+    return 1; /* yes, timed out */
+  if(secs < 0)
+    return 0; /* nope, not timed out */
+
+  /* if the full seconds were identical, check the sub second parts */
+  return (now->tv_usec - check->tv_usec >= 0);
+}
+
+/* add the specific number of milliseconds to the time in the first argument */
+int ares__timeadd(struct timeval *now,
+                  int millisecs)
+{
+  now->tv_sec += millisecs/1000;
+  now->tv_usec += (millisecs%1000)*1000;
+
+  if(now->tv_usec >= 1000000) {
+    ++(now->tv_sec);
+    now->tv_usec -= 1000000;
+  }
+
+  return 0;
+}
+
+/* return time offset between now and (future) check, in milliseconds */
+long ares__timeoffset(struct timeval *now,
+                      struct timeval *check)
+{
+  return (check->tv_sec - now->tv_sec)*1000 +
+         (check->tv_usec - now->tv_usec)/1000;
+}
+
+
+/* Something interesting happened on the wire, or there was a timeout.
+ * See what's up and respond accordingly.
+ */
+void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
+{
+  struct timeval now = ares__tvnow();
+
+  write_tcp_data(channel, write_fds, ARES_SOCKET_BAD, &now);
+  read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, &now);
+  read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, &now);
+  process_timeouts(channel, &now);
+  process_broken_connections(channel, &now);
+}
+
+/* Something interesting happened on the wire, or there was a timeout.
+ * See what's up and respond accordingly.
+ */
+void ares_process_fd(ares_channel channel,
+                     ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid
+                                               file descriptors */
+                     ares_socket_t write_fd)
+{
+  struct timeval now = ares__tvnow();
+
+  write_tcp_data(channel, NULL, write_fd, &now);
+  read_tcp_data(channel, NULL, read_fd, &now);
+  read_udp_packets(channel, NULL, read_fd, &now);
+  process_timeouts(channel, &now);
+}
+
+
+/* Return 1 if the specified error number describes a readiness error, or 0
+ * otherwise. This is mostly for HP-UX, which could return EAGAIN or
+ * EWOULDBLOCK. See this man page
+ *
+ *      http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html?manpage=/usr/share/man/man2.Z/send.2
+ */
+static int try_again(int errnum)
+{
+#if !defined EWOULDBLOCK && !defined EAGAIN
+#error "Neither EWOULDBLOCK nor EAGAIN defined"
+#endif
+  switch (errnum)
+    {
+#ifdef EWOULDBLOCK
+    case EWOULDBLOCK:
+      return 1;
+#endif
+#if defined EAGAIN && EAGAIN != EWOULDBLOCK
+    case EAGAIN:
+      return 1;
+#endif
+    }
+  return 0;
+}
+
+/* If any TCP sockets select true for writing, write out queued data
+ * we have for them.
+ */
+static void write_tcp_data(ares_channel channel,
+                           fd_set *write_fds,
+                           ares_socket_t write_fd,
+                           struct timeval *now)
+{
+  struct server_state *server;
+  struct send_request *sendreq;
+  struct iovec *vec;
+  int i;
+  ssize_t scount;
+  ssize_t wcount;
+  size_t n;
+
+  if(!write_fds && (write_fd == ARES_SOCKET_BAD))
+    /* no possible action */
+    return;
+
+  for (i = 0; i < channel->nservers; i++)
+    {
+      /* Make sure server has data to send and is selected in write_fds or
+         write_fd. */
+      server = &channel->servers[i];
+      if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD ||
+          server->is_broken)
+        continue;
+
+      if(write_fds) {
+        if(!FD_ISSET(server->tcp_socket, write_fds))
+          continue;
+      }
+      else {
+        if(server->tcp_socket != write_fd)
+          continue;
+      }
+
+      if(write_fds)
+        /* If there's an error and we close this socket, then open
+         * another with the same fd to talk to another server, then we
+         * don't want to think that it was the new socket that was
+         * ready. This is not disastrous, but is likely to result in
+         * extra system calls and confusion. */
+        FD_CLR(server->tcp_socket, write_fds);
+
+      /* Count the number of send queue items. */
+      n = 0;
+      for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+        n++;
+
+      /* Allocate iovecs so we can send all our data at once. */
+      vec = malloc(n * sizeof(struct iovec));
+      if (vec)
+        {
+          /* Fill in the iovecs and send. */
+          n = 0;
+          for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+            {
+              vec[n].iov_base = (char *) sendreq->data;
+              vec[n].iov_len = sendreq->len;
+              n++;
+            }
+          wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
+          free(vec);
+          if (wcount < 0)
+            {
+              if (!try_again(SOCKERRNO))
+                  handle_error(channel, i, now);
+              continue;
+            }
+
+          /* Advance the send queue by as many bytes as we sent. */
+          advance_tcp_send_queue(channel, i, wcount);
+        }
+      else
+        {
+          /* Can't allocate iovecs; just send the first request. */
+          sendreq = server->qhead;
+
+          scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
+          if (scount < 0)
+            {
+              if (!try_again(SOCKERRNO))
+                  handle_error(channel, i, now);
+              continue;
+            }
+
+          /* Advance the send queue by as many bytes as we sent. */
+          advance_tcp_send_queue(channel, i, scount);
+        }
+    }
+}
+
+/* Consume the given number of bytes from the head of the TCP send queue. */
+static void advance_tcp_send_queue(ares_channel channel, int whichserver,
+                                   ssize_t num_bytes)
+{
+  struct send_request *sendreq;
+  struct server_state *server = &channel->servers[whichserver];
+  while (num_bytes > 0)
+    {
+      sendreq = server->qhead;
+      if ((size_t)num_bytes >= sendreq->len)
+       {
+         num_bytes -= sendreq->len;
+         server->qhead = sendreq->next;
+         if (server->qhead == NULL)
+           {
+             SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
+             server->qtail = NULL;
+           }
+         if (sendreq->data_storage != NULL)
+           free(sendreq->data_storage);
+         free(sendreq);
+       }
+      else
+       {
+         sendreq->data += num_bytes;
+         sendreq->len -= num_bytes;
+         num_bytes = 0;
+       }
+    }
+}
+
+/* If any TCP socket selects true for reading, read some data,
+ * allocate a buffer if we finish reading the length word, and process
+ * a packet if we finish reading one.
+ */
+static void read_tcp_data(ares_channel channel, fd_set *read_fds,
+                          ares_socket_t read_fd, struct timeval *now)
+{
+  struct server_state *server;
+  int i;
+  ssize_t count;
+
+  if(!read_fds && (read_fd == ARES_SOCKET_BAD))
+    /* no possible action */
+    return;
+
+  for (i = 0; i < channel->nservers; i++)
+    {
+      /* Make sure the server has a socket and is selected in read_fds. */
+      server = &channel->servers[i];
+      if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
+        continue;
+
+      if(read_fds) {
+        if(!FD_ISSET(server->tcp_socket, read_fds))
+          continue;
+      }
+      else {
+        if(server->tcp_socket != read_fd)
+          continue;
+      }
+
+      if(read_fds)
+        /* If there's an error and we close this socket, then open
+         * another with the same fd to talk to another server, then we
+         * don't want to think that it was the new socket that was
+         * ready. This is not disastrous, but is likely to result in
+         * extra system calls and confusion. */
+        FD_CLR(server->tcp_socket, read_fds);
+
+      if (server->tcp_lenbuf_pos != 2)
+        {
+          /* We haven't yet read a length word, so read that (or
+           * what's left to read of it).
+           */
+          count = sread(server->tcp_socket,
+                        server->tcp_lenbuf + server->tcp_lenbuf_pos,
+                        2 - server->tcp_lenbuf_pos);
+          if (count <= 0)
+            {
+              if (!(count == -1 && try_again(SOCKERRNO)))
+                  handle_error(channel, i, now);
+              continue;
+            }
+
+          server->tcp_lenbuf_pos += (int)count;
+          if (server->tcp_lenbuf_pos == 2)
+            {
+              /* We finished reading the length word.  Decode the
+               * length and allocate a buffer for the data.
+               */
+              server->tcp_length = server->tcp_lenbuf[0] << 8
+                | server->tcp_lenbuf[1];
+              server->tcp_buffer = malloc(server->tcp_length);
+              if (!server->tcp_buffer)
+                handle_error(channel, i, now);
+              server->tcp_buffer_pos = 0;
+            }
+        }
+      else
+        {
+          /* Read data into the allocated buffer. */
+          count = sread(server->tcp_socket,
+                        server->tcp_buffer + server->tcp_buffer_pos,
+                        server->tcp_length - server->tcp_buffer_pos);
+          if (count <= 0)
+            {
+              if (!(count == -1 && try_again(SOCKERRNO)))
+                  handle_error(channel, i, now);
+              continue;
+            }
+
+          server->tcp_buffer_pos += (int)count;
+          if (server->tcp_buffer_pos == server->tcp_length)
+            {
+              /* We finished reading this answer; process it and
+               * prepare to read another length word.
+               */
+              process_answer(channel, server->tcp_buffer, server->tcp_length,
+                             i, 1, now);
+          if (server->tcp_buffer)
+                        free(server->tcp_buffer);
+              server->tcp_buffer = NULL;
+              server->tcp_lenbuf_pos = 0;
+              server->tcp_buffer_pos = 0;
+            }
+        }
+    }
+}
+
+/* If any UDP sockets select true for reading, process them. */
+static void read_udp_packets(ares_channel channel, fd_set *read_fds,
+                             ares_socket_t read_fd, struct timeval *now)
+{
+  struct server_state *server;
+  int i;
+  ssize_t count;
+  unsigned char buf[PACKETSZ + 1];
+#ifdef HAVE_RECVFROM
+  struct sockaddr_in from;
+  ares_socklen_t fromlen;
+#endif
+
+  if(!read_fds && (read_fd == ARES_SOCKET_BAD))
+    /* no possible action */
+    return;
+
+  for (i = 0; i < channel->nservers; i++)
+    {
+      /* Make sure the server has a socket and is selected in read_fds. */
+      server = &channel->servers[i];
+
+      if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken)
+        continue;
+
+      if(read_fds) {
+        if(!FD_ISSET(server->udp_socket, read_fds))
+          continue;
+      }
+      else {
+        if(server->udp_socket != read_fd)
+          continue;
+      }
+
+      if(read_fds)
+        /* If there's an error and we close this socket, then open
+         * another with the same fd to talk to another server, then we
+         * don't want to think that it was the new socket that was
+         * ready. This is not disastrous, but is likely to result in
+         * extra system calls and confusion. */
+        FD_CLR(server->udp_socket, read_fds);
+
+      /* To reduce event loop overhead, read and process as many
+       * packets as we can. */
+      do {
+#ifdef HAVE_RECVFROM
+        fromlen = sizeof(from);
+        count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf),
+                                  0, (struct sockaddr *)&from, &fromlen);
+#else
+        count = sread(server->udp_socket, buf, sizeof(buf));
+#endif
+        if (count == -1 && try_again(SOCKERRNO))
+          continue;
+        else if (count <= 0)
+          handle_error(channel, i, now);
+#ifdef HAVE_RECVFROM
+        else if (from.sin_addr.s_addr != server->addr.s_addr)
+          /* Address response came from did not match the address
+           * we sent the request to.  Someone may be attempting
+           * to perform a cache poisoning attack */
+          break;
+#endif
+        else
+          process_answer(channel, buf, (int)count, i, 0, now);
+       } while (count > 0);
+    }
+}
+
+/* If any queries have timed out, note the timeout and move them on. */
+static void process_timeouts(ares_channel channel, struct timeval *now)
+{
+  time_t t;  /* the time of the timeouts we're processing */
+  struct query *query;
+  struct list_node* list_head;
+  struct list_node* list_node;
+
+  /* Process all the timeouts that have fired since the last time we
+   * processed timeouts. If things are going well, then we'll have
+   * hundreds/thousands of queries that fall into future buckets, and
+   * only a handful of requests that fall into the "now" bucket, so
+   * this should be quite quick.
+   */
+  for (t = channel->last_timeout_processed; t <= now->tv_sec; t++)
+    {
+      list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]);
+      for (list_node = list_head->next; list_node != list_head; )
+        {
+          query = list_node->data;
+          list_node = list_node->next;  /* in case the query gets deleted */
+          if (query->timeout.tv_sec && ares__timedout(now, &query->timeout))
+            {
+              query->error_status = ARES_ETIMEOUT;
+              ++query->timeouts;
+              next_server(channel, query, now);
+            }
+        }
+     }
+  channel->last_timeout_processed = now->tv_sec;
+}
+
+/* Handle an answer from a server. */
+static void process_answer(ares_channel channel, unsigned char *abuf,
+                           int alen, int whichserver, int tcp,
+                           struct timeval *now)
+{
+  int tc, rcode;
+  unsigned short id;
+  struct query *query;
+  struct list_node* list_head;
+  struct list_node* list_node;
+
+  /* If there's no room in the answer for a header, we can't do much
+   * with it. */
+  if (alen < HFIXEDSZ)
+    return;
+
+  /* Grab the query ID, truncate bit, and response code from the packet. */
+  id = DNS_HEADER_QID(abuf);
+  tc = DNS_HEADER_TC(abuf);
+  rcode = DNS_HEADER_RCODE(abuf);
+
+  /* Find the query corresponding to this packet. The queries are
+   * hashed/bucketed by query id, so this lookup should be quick.
+   * Note that both the query id and the questions must be the same;
+   * when the query id wraps around we can have multiple outstanding
+   * queries with the same query id, so we need to check both the id and
+   * question.
+   */
+  query = NULL;
+  list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]);
+  for (list_node = list_head->next; list_node != list_head;
+       list_node = list_node->next)
+    {
+      struct query *q = list_node->data;
+      if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen))
+        {
+          query = q;
+          break;
+        }
+    }
+  if (!query)
+    return;
+
+  /* If we got a truncated UDP packet and are not ignoring truncation,
+   * don't accept the packet, and switch the query to TCP if we hadn't
+   * done so already.
+   */
+  if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC))
+    {
+      if (!query->using_tcp)
+        {
+          query->using_tcp = 1;
+          ares__send_query(channel, query, now);
+        }
+      return;
+    }
+
+  /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we
+   * are ignoring truncation.
+   */
+  if (alen > PACKETSZ && !tcp)
+    alen = PACKETSZ;
+
+  /* If we aren't passing through all error packets, discard packets
+   * with SERVFAIL, NOTIMP, or REFUSED response codes.
+   */
+  if (!(channel->flags & ARES_FLAG_NOCHECKRESP))
+    {
+      if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
+        {
+          skip_server(channel, query, whichserver);
+          if (query->server == whichserver)
+            next_server(channel, query, now);
+          return;
+        }
+    }
+
+  end_query(channel, query, ARES_SUCCESS, abuf, alen);
+}
+
+/* Close all the connections that are no longer usable. */
+static void process_broken_connections(ares_channel channel,
+                                       struct timeval *now)
+{
+  int i;
+  for (i = 0; i < channel->nservers; i++)
+    {
+      struct server_state *server = &channel->servers[i];
+      if (server->is_broken)
+        {
+          handle_error(channel, i, now);
+        }
+    }
+}
+
+static void handle_error(ares_channel channel, int whichserver,
+                         struct timeval *now)
+{
+  struct server_state *server;
+  struct query *query;
+  struct list_node list_head;
+  struct list_node* list_node;
+
+  server = &channel->servers[whichserver];
+
+  /* Reset communications with this server. */
+  ares__close_sockets(channel, server);
+
+  /* Tell all queries talking to this server to move on and not try
+   * this server again. We steal the current list of queries that were
+   * in-flight to this server, since when we call next_server this can
+   * cause the queries to be re-sent to this server, which will
+   * re-insert these queries in that same server->queries_to_server
+   * list.
+   */
+  ares__init_list_head(&list_head);
+  ares__swap_lists(&list_head, &(server->queries_to_server));
+  for (list_node = list_head.next; list_node != &list_head; )
+    {
+      query = list_node->data;
+      list_node = list_node->next;  /* in case the query gets deleted */
+      assert(query->server == whichserver);
+      skip_server(channel, query, whichserver);
+      next_server(channel, query, now);
+    }
+  /* Each query should have removed itself from our temporary list as
+   * it re-sent itself or finished up...
+   */
+  assert(ares__is_list_empty(&list_head));
+}
+
+static void skip_server(ares_channel channel, struct query *query,
+                        int whichserver) {
+  /* The given server gave us problems with this query, so if we have
+   * the luxury of using other servers, then let's skip the
+   * potentially broken server and just use the others. If we only
+   * have one server and we need to retry then we should just go ahead
+   * and re-use that server, since it's our only hope; perhaps we
+   * just got unlucky, and retrying will work (eg, the server timed
+   * out our TCP connection just as we were sending another request).
+   */
+  if (channel->nservers > 1)
+    {
+      query->server_info[whichserver].skip_server = 1;
+    }
+}
+
+static void next_server(ares_channel channel, struct query *query,
+                        struct timeval *now)
+{
+  /* We need to try each server channel->tries times. We have channel->nservers
+   * servers to try. In total, we need to do channel->nservers * channel->tries
+   * attempts. Use query->try to remember how many times we already attempted
+   * this query. Use modular arithmetic to find the next server to try. */
+  while (++(query->try) < (channel->nservers * channel->tries))
+    {
+      struct server_state *server;
+
+      /* Move on to the next server. */
+      query->server = (query->server + 1) % channel->nservers;
+      server = &channel->servers[query->server];
+
+      /* We don't want to use this server if (1) we decided this
+       * connection is broken, and thus about to be closed, (2)
+       * we've decided to skip this server because of earlier
+       * errors we encountered, or (3) we already sent this query
+       * over this exact connection.
+       */
+      if (!server->is_broken &&
+           !query->server_info[query->server].skip_server &&
+           !(query->using_tcp &&
+             (query->server_info[query->server].tcp_connection_generation ==
+              server->tcp_connection_generation)))
+        {
+           ares__send_query(channel, query, now);
+           return;
+        }
+
+      /* You might think that with TCP we only need one try. However,
+       * even when using TCP, servers can time-out our connection just
+       * as we're sending a request, or close our connection because
+       * they die, or never send us a reply because they get wedged or
+       * tickle a bug that drops our request.
+       */
+    }
+
+  /* If we are here, all attempts to perform query failed. */
+  end_query(channel, query, query->error_status, NULL, 0);
+}
+
+void ares__send_query(ares_channel channel, struct query *query,
+                      struct timeval *now)
+{
+  struct send_request *sendreq;
+  struct server_state *server;
+  int timeplus;
+
+  server = &channel->servers[query->server];
+  if (query->using_tcp)
+    {
+      /* Make sure the TCP socket for this server is set up and queue
+       * a send request.
+       */
+      if (server->tcp_socket == ARES_SOCKET_BAD)
+        {
+          if (open_tcp_socket(channel, server) == -1)
+            {
+              skip_server(channel, query, query->server);
+              next_server(channel, query, now);
+              return;
+            }
+        }
+      sendreq = calloc(1, sizeof(struct send_request));
+      if (!sendreq)
+        {
+        end_query(channel, query, ARES_ENOMEM, NULL, 0);
+          return;
+        }
+      /* To make the common case fast, we avoid copies by using the
+       * query's tcpbuf for as long as the query is alive. In the rare
+       * case where the query ends while it's queued for transmission,
+       * then we give the sendreq its own copy of the request packet
+       * and put it in sendreq->data_storage.
+       */
+      sendreq->data_storage = NULL;
+      sendreq->data = query->tcpbuf;
+      sendreq->len = query->tcplen;
+      sendreq->owner_query = query;
+      sendreq->next = NULL;
+      if (server->qtail)
+        server->qtail->next = sendreq;
+      else
+        {
+          SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
+          server->qhead = sendreq;
+        }
+      server->qtail = sendreq;
+      query->server_info[query->server].tcp_connection_generation =
+        server->tcp_connection_generation;
+    }
+  else
+    {
+      if (server->udp_socket == ARES_SOCKET_BAD)
+        {
+          if (open_udp_socket(channel, server) == -1)
+            {
+              skip_server(channel, query, query->server);
+              next_server(channel, query, now);
+              return;
+            }
+        }
+      if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
+        {
+          /* FIXME: Handle EAGAIN here since it likely can happen. */
+          skip_server(channel, query, query->server);
+          next_server(channel, query, now);
+          return;
+        }
+    }
+    timeplus = channel->timeout << (query->try / channel->nservers);
+    timeplus = (timeplus * (9 + (rand () & 7))) / 16;
+    query->timeout = *now;
+    ares__timeadd(&query->timeout,
+                  timeplus);
+    /* Keep track of queries bucketed by timeout, so we can process
+     * timeout events quickly.
+     */
+    ares__remove_from_list(&(query->queries_by_timeout));
+    ares__insert_in_list(
+        &(query->queries_by_timeout),
+        &(channel->queries_by_timeout[query->timeout.tv_sec %
+                                      ARES_TIMEOUT_TABLE_SIZE]));
+
+    /* Keep track of queries bucketed by server, so we can process server
+     * errors quickly.
+     */
+    ares__remove_from_list(&(query->queries_to_server));
+    ares__insert_in_list(&(query->queries_to_server),
+                         &(server->queries_to_server));
+}
+
+/*
+ * setsocknonblock sets the given socket to either blocking or non-blocking mode
+ * based on the 'nonblock' boolean argument. This function is highly portable.
+ */
+static int setsocknonblock(ares_socket_t sockfd,    /* operate on this */
+                    int nonblock   /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+  return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+  /* most recent unix versions */
+  int flags;
+  flags = fcntl(sockfd, F_GETFL, 0);
+  if (FALSE != nonblock)
+    return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+  else
+    return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+  /* older unix versions */
+  int flags;
+  flags = nonblock;
+  return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+#ifdef WATT32
+  char flags;
+#else
+  /* Windows */
+  unsigned long flags;
+#endif
+  flags = nonblock;
+  return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+  /* Amiga */
+  return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+  /* BeOS */
+  long b = nonblock ? 1 : 0;
+  return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+#  error "no non-blocking method was found/used/set"
+#endif
+}
+
+static int configure_socket(int s, ares_channel channel)
+{
+  setsocknonblock(s, TRUE);
+
+#if defined(FD_CLOEXEC) && !defined(MSDOS)
+  /* Configure the socket fd as close-on-exec. */
+  if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
+    return -1;
+#endif
+
+  /* Set the socket's send and receive buffer sizes. */
+  if ((channel->socket_send_buffer_size > 0) &&
+      setsockopt(s, SOL_SOCKET, SO_SNDBUF,
+                 (void *)&channel->socket_send_buffer_size,
+                 sizeof(channel->socket_send_buffer_size)) == -1)
+    return -1;
+
+  if ((channel->socket_receive_buffer_size > 0) &&
+      setsockopt(s, SOL_SOCKET, SO_RCVBUF,
+                 (void *)&channel->socket_receive_buffer_size,
+                 sizeof(channel->socket_receive_buffer_size)) == -1)
+    return -1;
+
+  return 0;
+ }
+
+static int open_tcp_socket(ares_channel channel, struct server_state *server)
+{
+  ares_socket_t s;
+  int opt;
+  struct sockaddr_in sockin;
+
+  /* Acquire a socket. */
+  s = socket(AF_INET, SOCK_STREAM, 0);
+  if (s == ARES_SOCKET_BAD)
+    return -1;
+
+  /* Configure it. */
+  if (configure_socket(s, channel) < 0)
+    {
+       sclose(s);
+       return -1;
+    }
+
+#ifdef TCP_NODELAY
+  /*
+   * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in
+   * configure_socket). In general, in DNS lookups we're pretty much interested
+   * in firing off a single request and then waiting for a reply, so batching
+   * isn't very interesting in general.
+   */
+  opt = 1;
+  if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+                 (void *)&opt, sizeof(opt)) == -1)
+    {
+       sclose(s);
+       return -1;
+    }
+#endif
+
+  /* Connect to the server. */
+  memset(&sockin, 0, sizeof(sockin));
+  sockin.sin_family = AF_INET;
+  sockin.sin_addr = server->addr;
+  sockin.sin_port = (unsigned short)(channel->tcp_port & 0xffff);
+  if (connect(s, (struct sockaddr *) &sockin, sizeof(sockin)) == -1)
+    {
+      int err = SOCKERRNO;
+
+      if (err != EINPROGRESS && err != EWOULDBLOCK)
+        {
+          sclose(s);
+          return -1;
+        }
+    }
+
+  if (channel->sock_create_cb)
+    {
+      int err = channel->sock_create_cb(s, SOCK_STREAM,
+                                        channel->sock_create_cb_data);
+      if (err < 0)
+        {
+          sclose(s);
+          return err;
+        }
+    }
+
+  SOCK_STATE_CALLBACK(channel, s, 1, 0);
+  server->tcp_buffer_pos = 0;
+  server->tcp_socket = s;
+  server->tcp_connection_generation = ++channel->tcp_connection_generation;
+  return 0;
+}
+
+static int open_udp_socket(ares_channel channel, struct server_state *server)
+{
+  ares_socket_t s;
+  struct sockaddr_in sockin;
+
+  /* Acquire a socket. */
+  s = socket(AF_INET, SOCK_DGRAM, 0);
+  if (s == ARES_SOCKET_BAD)
+    return -1;
+
+  /* Set the socket non-blocking. */
+  if (configure_socket(s, channel) < 0)
+    {
+       sclose(s);
+       return -1;
+    }
+
+  /* Connect to the server. */
+  memset(&sockin, 0, sizeof(sockin));
+  sockin.sin_family = AF_INET;
+  sockin.sin_addr = server->addr;
+  sockin.sin_port = (unsigned short)(channel->udp_port & 0xffff);
+  if (connect(s, (struct sockaddr *) &sockin, sizeof(sockin)) == -1)
+    {
+      int err = SOCKERRNO;
+
+      if (err != EINPROGRESS && err != EWOULDBLOCK)
+        {
+          sclose(s);
+          return -1;
+        }
+    }
+
+  if (channel->sock_create_cb)
+    {
+      int err = channel->sock_create_cb(s, SOCK_DGRAM,
+                                        channel->sock_create_cb_data);
+      if (err < 0)
+        {
+          sclose(s);
+          return err;
+        }
+    }
+
+  SOCK_STATE_CALLBACK(channel, s, 1, 0);
+
+  server->udp_socket = s;
+  return 0;
+}
+
+static int same_questions(const unsigned char *qbuf, int qlen,
+                          const unsigned char *abuf, int alen)
+{
+  struct {
+    const unsigned char *p;
+    int qdcount;
+    char *name;
+    long namelen;
+    int type;
+    int dnsclass;
+  } q, a;
+  int i, j;
+
+  if (qlen < HFIXEDSZ || alen < HFIXEDSZ)
+    return 0;
+
+  /* Extract qdcount from the request and reply buffers and compare them. */
+  q.qdcount = DNS_HEADER_QDCOUNT(qbuf);
+  a.qdcount = DNS_HEADER_QDCOUNT(abuf);
+  if (q.qdcount != a.qdcount)
+    return 0;
+
+  /* For each question in qbuf, find it in abuf. */
+  q.p = qbuf + HFIXEDSZ;
+  for (i = 0; i < q.qdcount; i++)
+    {
+      /* Decode the question in the query. */
+      if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen)
+          != ARES_SUCCESS)
+        return 0;
+      q.p += q.namelen;
+      if (q.p + QFIXEDSZ > qbuf + qlen)
+        {
+          free(q.name);
+          return 0;
+        }
+      q.type = DNS_QUESTION_TYPE(q.p);
+      q.dnsclass = DNS_QUESTION_CLASS(q.p);
+      q.p += QFIXEDSZ;
+
+      /* Search for this question in the answer. */
+      a.p = abuf + HFIXEDSZ;
+      for (j = 0; j < a.qdcount; j++)
+        {
+          /* Decode the question in the answer. */
+          if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)
+              != ARES_SUCCESS)
+            {
+              free(q.name);
+              return 0;
+            }
+          a.p += a.namelen;
+          if (a.p + QFIXEDSZ > abuf + alen)
+            {
+              free(q.name);
+              free(a.name);
+              return 0;
+            }
+          a.type = DNS_QUESTION_TYPE(a.p);
+          a.dnsclass = DNS_QUESTION_CLASS(a.p);
+          a.p += QFIXEDSZ;
+
+          /* Compare the decoded questions. */
+          if (strcasecmp(q.name, a.name) == 0 && q.type == a.type
+              && q.dnsclass == a.dnsclass)
+            {
+              free(a.name);
+              break;
+            }
+          free(a.name);
+        }
+
+      free(q.name);
+      if (j == a.qdcount)
+        return 0;
+    }
+  return 1;
+}
+
+static void end_query (ares_channel channel, struct query *query, int status,
+                       unsigned char *abuf, int alen)
+{
+  int i;
+
+  /* First we check to see if this query ended while one of our send
+   * queues still has pointers to it.
+   */
+  for (i = 0; i < channel->nservers; i++)
+    {
+      struct server_state *server = &channel->servers[i];
+      struct send_request *sendreq;
+      for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
+        if (sendreq->owner_query == query)
+          {
+            sendreq->owner_query = NULL;
+            assert(sendreq->data_storage == NULL);
+            if (status == ARES_SUCCESS)
+              {
+                /* We got a reply for this query, but this queued
+                 * sendreq points into this soon-to-be-gone query's
+                 * tcpbuf. Probably this means we timed out and queued
+                 * the query for retransmission, then received a
+                 * response before actually retransmitting. This is
+                 * perfectly fine, so we want to keep the connection
+                 * running smoothly if we can. But in the worst case
+                 * we may have sent only some prefix of the query,
+                 * with some suffix of the query left to send. Also,
+                 * the buffer may be queued on multiple queues. To
+                 * prevent dangling pointers to the query's tcpbuf and
+                 * handle these cases, we just give such sendreqs
+                 * their own copy of the query packet.
+                 */
+               sendreq->data_storage = malloc(sendreq->len);
+               if (sendreq->data_storage != NULL)
+                 {
+                   memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
+                   sendreq->data = sendreq->data_storage;
+                 }
+              }
+            if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL))
+              {
+                /* We encountered an error (probably a timeout,
+                 * suggesting the DNS server we're talking to is
+                 * probably unreachable, wedged, or severely
+                 * overloaded) or we couldn't copy the request, so
+                 * mark the connection as broken. When we get to
+                 * process_broken_connections() we'll close the
+                 * connection and try to re-send requests to another
+                 * server.
+                 */
+               server->is_broken = 1;
+               /* Just to be paranoid, zero out this sendreq... */
+               sendreq->data = NULL;
+               sendreq->len = 0;
+             }
+          }
+    }
+
+  /* Invoke the callback */
+  query->callback(query->arg, status, query->timeouts, abuf, alen);
+  ares__free_query(query);
+
+  /* Simple cleanup policy: if no queries are remaining, close all
+   * network sockets unless STAYOPEN is set.
+   */
+  if (!(channel->flags & ARES_FLAG_STAYOPEN) &&
+      ares__is_list_empty(&(channel->all_queries)))
+    {
+      for (i = 0; i < channel->nservers; i++)
+        ares__close_sockets(channel, &channel->servers[i]);
+    }
+}
+
+void ares__free_query(struct query *query)
+{
+  /* Remove the query from all the lists in which it is linked */
+  ares__remove_from_list(&(query->queries_by_qid));
+  ares__remove_from_list(&(query->queries_by_timeout));
+  ares__remove_from_list(&(query->queries_to_server));
+  ares__remove_from_list(&(query->all_queries));
+  /* Zero out some important stuff, to help catch bugs */
+  query->callback = NULL;
+  query->arg = NULL;
+  /* Deallocate the memory associated with the query */
+  free(query->tcpbuf);
+  free(query->server_info);
+  free(query);
+}
diff --git a/3rdParty/CAres/src/ares_query.c b/3rdParty/CAres/src/ares_query.c
new file mode 100644
index 0000000..7052d7a
--- /dev/null
+++ b/3rdParty/CAres/src/ares_query.c
@@ -0,0 +1,184 @@
+/* $Id: ares_query.c,v 1.21 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+struct qquery {
+  ares_callback callback;
+  void *arg;
+};
+
+static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen);
+
+void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
+{
+  unsigned char x;
+  unsigned char y;
+  unsigned char* state;
+  unsigned char xorIndex;
+  short counter;
+
+  x = key->x;
+  y = key->y;
+
+  state = &key->state[0];
+  for(counter = 0; counter < buffer_len; counter ++)
+  {
+    x = (unsigned char)((x + 1) % 256);
+    y = (unsigned char)((state[x] + y) % 256);
+    ARES_SWAP_BYTE(&state[x], &state[y]);
+
+    xorIndex = (unsigned char)((state[x] + state[y]) % 256);
+
+    buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]);
+  }
+  key->x = x;
+  key->y = y;
+}
+
+static struct query* find_query_by_id(ares_channel channel, unsigned short id)
+{
+  unsigned short qid;
+  struct list_node* list_head;
+  struct list_node* list_node;
+  DNS_HEADER_SET_QID(((unsigned char*)&qid), id);
+
+  /* Find the query corresponding to this packet. */
+  list_head = &(channel->queries_by_qid[qid % ARES_QID_TABLE_SIZE]);
+  for (list_node = list_head->next; list_node != list_head;
+       list_node = list_node->next)
+    {
+       struct query *q = list_node->data;
+       if (q->qid == qid)
+	  return q;
+    }
+  return NULL;
+}
+
+
+/* a unique query id is generated using an rc4 key. Since the id may already
+   be used by a running query (as infrequent as it may be), a lookup is
+   performed per id generation. In practice this search should happen only
+   once per newly generated id
+*/
+static unsigned short generate_unique_id(ares_channel channel)
+{
+  unsigned short id;
+
+  do {
+    id = ares__generate_new_id(&channel->id_key);
+  } while (find_query_by_id(channel, id));
+
+  return (unsigned short)id;
+}
+
+void ares_query(ares_channel channel, const char *name, int dnsclass,
+                int type, ares_callback callback, void *arg)
+{
+  struct qquery *qquery;
+  unsigned char *qbuf;
+  int qlen, rd, status;
+
+  /* Compose the query. */
+  rd = !(channel->flags & ARES_FLAG_NORECURSE);
+  status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf,
+                        &qlen);
+  if (status != ARES_SUCCESS)
+    {
+      if (qbuf != NULL) free(qbuf);
+      callback(arg, status, 0, NULL, 0);
+      return;
+    }
+
+  channel->next_id = generate_unique_id(channel);
+
+  /* Allocate and fill in the query structure. */
+  qquery = malloc(sizeof(struct qquery));
+  if (!qquery)
+    {
+      ares_free_string(qbuf);
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+  qquery->callback = callback;
+  qquery->arg = arg;
+
+  /* Send it off.  qcallback will be called when we get an answer. */
+  ares_send(channel, qbuf, qlen, qcallback, qquery);
+  ares_free_string(qbuf);
+}
+
+static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen)
+{
+  struct qquery *qquery = (struct qquery *) arg;
+  unsigned int ancount;
+  int rcode;
+
+  if (status != ARES_SUCCESS)
+    qquery->callback(qquery->arg, status, timeouts, abuf, alen);
+  else
+    {
+      /* Pull the response code and answer count from the packet. */
+      rcode = DNS_HEADER_RCODE(abuf);
+      ancount = DNS_HEADER_ANCOUNT(abuf);
+
+      /* Convert errors. */
+      switch (rcode)
+        {
+        case NOERROR:
+          status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA;
+          break;
+        case FORMERR:
+          status = ARES_EFORMERR;
+          break;
+        case SERVFAIL:
+          status = ARES_ESERVFAIL;
+          break;
+        case NXDOMAIN:
+          status = ARES_ENOTFOUND;
+          break;
+        case NOTIMP:
+          status = ARES_ENOTIMP;
+          break;
+        case REFUSED:
+          status = ARES_EREFUSED;
+          break;
+        }
+      qquery->callback(qquery->arg, status, timeouts, abuf, alen);
+    }
+  free(qquery);
+}
diff --git a/3rdParty/CAres/src/ares_rules.h b/3rdParty/CAres/src/ares_rules.h
new file mode 100644
index 0000000..65bc1eb
--- /dev/null
+++ b/3rdParty/CAres/src/ares_rules.h
@@ -0,0 +1,145 @@
+#ifndef __CARES_RULES_H
+#define __CARES_RULES_H
+
+/* $Id: ares_rules.h,v 1.3 2009-10-27 16:56:20 yangtse Exp $ */
+
+/* Copyright (C) 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/*                    COMPILE TIME SANITY CHECKS                    */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by ares.h when an application is
+ * being built using an already built c-ares library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the ares_build.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * c-ares library user nor by the c-ares library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the c-ares development mailing list:
+ * http://cool.haxx.se/mailman/listinfo/c-ares/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ *   "negative subscript or subscript is too large"
+ *   "array must have at least one element"
+ *   "-1 is an illegal array size"
+ *   "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built c-ares library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CARES_SIZEOF_LONG
+#  error "CARES_SIZEOF_LONG definition is missing!"
+   Error Compilation_aborted_CARES_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CARES_TYPEOF_ARES_SOCKLEN_T
+#  error "CARES_TYPEOF_ARES_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CARES_SIZEOF_ARES_SOCKLEN_T
+#  error "CARES_SIZEOF_ARES_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CareschkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CareschkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+  __cares_rule_01__
+    [CareschkszEQ(long, CARES_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * ares_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+  __cares_rule_02__
+    [CareschkszEQ(ares_socklen_t, CARES_SIZEOF_ARES_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of ares_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+  __cares_rule_03__
+    [CareschkszGE(ares_socklen_t, int)];
+
+/* ================================================================ */
+/*          EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS           */
+/* ================================================================ */
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CareschkszEQ
+#undef CareschkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CARES_PULL_WS2TCPIP_H
+#undef CARES_PULL_SYS_TYPES_H
+#undef CARES_PULL_SYS_SOCKET_H
+
+#undef CARES_TYPEOF_ARES_SOCKLEN_T
+
+#endif /* __CARES_RULES_H */
diff --git a/3rdParty/CAres/src/ares_search.c b/3rdParty/CAres/src/ares_search.c
new file mode 100644
index 0000000..9a44397
--- /dev/null
+++ b/3rdParty/CAres/src/ares_search.c
@@ -0,0 +1,323 @@
+/* $Id: ares_search.c,v 1.20 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+struct search_query {
+  /* Arguments passed to ares_search */
+  ares_channel channel;
+  char *name;                   /* copied into an allocated buffer */
+  int dnsclass;
+  int type;
+  ares_callback callback;
+  void *arg;
+
+  int status_as_is;             /* error status from trying as-is */
+  int next_domain;              /* next search domain to try */
+  int trying_as_is;             /* current query is for name as-is */
+  int timeouts;                 /* number of timeouts we saw for this request */
+  int ever_got_nodata;          /* did we ever get ARES_ENODATA along the way? */
+};
+
+static void search_callback(void *arg, int status, int timeouts,
+                            unsigned char *abuf, int alen);
+static void end_squery(struct search_query *squery, int status,
+                       unsigned char *abuf, int alen);
+static int cat_domain(const char *name, const char *domain, char **s);
+static int single_domain(ares_channel channel, const char *name, char **s);
+
+void ares_search(ares_channel channel, const char *name, int dnsclass,
+                 int type, ares_callback callback, void *arg)
+{
+  struct search_query *squery;
+  char *s;
+  const char *p;
+  int status, ndots;
+
+  /* If name only yields one domain to search, then we don't have
+   * to keep extra state, so just do an ares_query().
+   */
+  status = single_domain(channel, name, &s);
+  if (status != ARES_SUCCESS)
+    {
+      callback(arg, status, 0, NULL, 0);
+      return;
+    }
+  if (s)
+    {
+      ares_query(channel, s, dnsclass, type, callback, arg);
+      free(s);
+      return;
+    }
+
+  /* Allocate a search_query structure to hold the state necessary for
+   * doing multiple lookups.
+   */
+  squery = malloc(sizeof(struct search_query));
+  if (!squery)
+    {
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+  squery->channel = channel;
+  squery->name = strdup(name);
+  if (!squery->name)
+    {
+      free(squery);
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+  squery->dnsclass = dnsclass;
+  squery->type = type;
+  squery->status_as_is = -1;
+  squery->callback = callback;
+  squery->arg = arg;
+  squery->timeouts = 0;
+  squery->ever_got_nodata = 0;
+
+  /* Count the number of dots in name. */
+  ndots = 0;
+  for (p = name; *p; p++)
+    {
+      if (*p == '.')
+        ndots++;
+    }
+
+  /* If ndots is at least the channel ndots threshold (usually 1),
+   * then we try the name as-is first.  Otherwise, we try the name
+   * as-is last.
+   */
+  if (ndots >= channel->ndots)
+    {
+      /* Try the name as-is first. */
+      squery->next_domain = 0;
+      squery->trying_as_is = 1;
+      ares_query(channel, name, dnsclass, type, search_callback, squery);
+    }
+  else
+    {
+      /* Try the name as-is last; start with the first search domain. */
+      squery->next_domain = 1;
+      squery->trying_as_is = 0;
+      status = cat_domain(name, channel->domains[0], &s);
+      if (status == ARES_SUCCESS)
+        {
+          ares_query(channel, s, dnsclass, type, search_callback, squery);
+          free(s);
+        }
+      else
+      {
+        /* failed, free the malloc()ed memory */
+        free(squery->name);
+        free(squery);
+        callback(arg, status, 0, NULL, 0);
+      }
+    }
+}
+
+static void search_callback(void *arg, int status, int timeouts,
+                            unsigned char *abuf, int alen)
+{
+  struct search_query *squery = (struct search_query *) arg;
+  ares_channel channel = squery->channel;
+  char *s;
+
+  squery->timeouts += timeouts;
+
+  /* Stop searching unless we got a non-fatal error. */
+  if (status != ARES_ENODATA && status != ARES_ESERVFAIL
+      && status != ARES_ENOTFOUND)
+    end_squery(squery, status, abuf, alen);
+  else
+    {
+      /* Save the status if we were trying as-is. */
+      if (squery->trying_as_is)
+        squery->status_as_is = status;
+
+      /*
+       * If we ever get ARES_ENODATA along the way, record that; if the search
+       * should run to the very end and we got at least one ARES_ENODATA,
+       * then callers like ares_gethostbyname() may want to try a T_A search
+       * even if the last domain we queried for T_AAAA resource records
+       * returned ARES_ENOTFOUND.
+       */
+      if (status == ARES_ENODATA)
+        squery->ever_got_nodata = 1;
+
+      if (squery->next_domain < channel->ndomains)
+        {
+          /* Try the next domain. */
+          status = cat_domain(squery->name,
+                              channel->domains[squery->next_domain], &s);
+          if (status != ARES_SUCCESS)
+            end_squery(squery, status, NULL, 0);
+          else
+            {
+              squery->trying_as_is = 0;
+              squery->next_domain++;
+              ares_query(channel, s, squery->dnsclass, squery->type,
+                         search_callback, squery);
+              free(s);
+            }
+        }
+      else if (squery->status_as_is == -1)
+        {
+          /* Try the name as-is at the end. */
+          squery->trying_as_is = 1;
+          ares_query(channel, squery->name, squery->dnsclass, squery->type,
+                     search_callback, squery);
+        }
+      else {
+        if (squery->status_as_is == ARES_ENOTFOUND && squery->ever_got_nodata) {
+          end_squery(squery, ARES_ENODATA, NULL, 0);
+        }
+        else
+          end_squery(squery, squery->status_as_is, NULL, 0);
+      }
+    }
+}
+
+static void end_squery(struct search_query *squery, int status,
+                       unsigned char *abuf, int alen)
+{
+  squery->callback(squery->arg, status, squery->timeouts, abuf, alen);
+  free(squery->name);
+  free(squery);
+}
+
+/* Concatenate two domains. */
+static int cat_domain(const char *name, const char *domain, char **s)
+{
+  size_t nlen = strlen(name);
+  size_t dlen = strlen(domain);
+
+  *s = malloc(nlen + 1 + dlen + 1);
+  if (!*s)
+    return ARES_ENOMEM;
+  memcpy(*s, name, nlen);
+  (*s)[nlen] = '.';
+  memcpy(*s + nlen + 1, domain, dlen);
+  (*s)[nlen + 1 + dlen] = 0;
+  return ARES_SUCCESS;
+}
+
+/* Determine if this name only yields one query.  If it does, set *s to
+ * the string we should query, in an allocated buffer.  If not, set *s
+ * to NULL.
+ */
+static int single_domain(ares_channel channel, const char *name, char **s)
+{
+  size_t len = strlen(name);
+  const char *hostaliases;
+  FILE *fp;
+  char *line = NULL;
+  int status;
+  size_t linesize;
+  const char *p, *q;
+  int error;
+
+  /* If the name contains a trailing dot, then the single query is the name
+   * sans the trailing dot.
+   */
+  if (name[len - 1] == '.')
+    {
+      *s = strdup(name);
+      return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
+    }
+
+  if (!(channel->flags & ARES_FLAG_NOALIASES) && !strchr(name, '.'))
+    {
+      /* The name might be a host alias. */
+      hostaliases = getenv("HOSTALIASES");
+      if (hostaliases)
+        {
+          fp = fopen(hostaliases, "r");
+          if (fp)
+            {
+              while ((status = ares__read_line(fp, &line, &linesize))
+                     == ARES_SUCCESS)
+                {
+                  if (strncasecmp(line, name, len) != 0 ||
+                      !ISSPACE(line[len]))
+                    continue;
+                  p = line + len;
+                  while (ISSPACE(*p))
+                    p++;
+                  if (*p)
+                    {
+                      q = p + 1;
+                      while (*q && !ISSPACE(*q))
+                        q++;
+                      *s = malloc(q - p + 1);
+                      if (*s)
+                        {
+                          memcpy(*s, p, q - p);
+                          (*s)[q - p] = 0;
+                        }
+                      free(line);
+                      fclose(fp);
+                      return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
+                    }
+                }
+              free(line);
+              fclose(fp);
+              if (status != ARES_SUCCESS)
+                return status;
+            }
+          else
+            {
+              error = errno;
+              switch(error)
+                {
+                case ENOENT:
+                case ESRCH:
+                  break;
+                default:
+                  DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
+                                 error, strerror(error)));
+                  DEBUGF(fprintf(stderr, "Error opening file: %s\n",
+                                 hostaliases));
+                  *s = NULL;
+                  return ARES_EFILE;
+                }
+            }
+        }
+    }
+
+  if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0)
+    {
+      /* No domain search to do; just try the name as-is. */
+      *s = strdup(name);
+      return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
+    }
+
+  *s = NULL;
+  return ARES_SUCCESS;
+}
diff --git a/3rdParty/CAres/src/ares_send.c b/3rdParty/CAres/src/ares_send.c
new file mode 100644
index 0000000..eb35b47
--- /dev/null
+++ b/3rdParty/CAres/src/ares_send.c
@@ -0,0 +1,135 @@
+/* $Id: ares_send.c,v 1.21 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
+               ares_callback callback, void *arg)
+{
+  struct query *query;
+  int i;
+  struct timeval now;
+
+  /* Verify that the query is at least long enough to hold the header. */
+  if (qlen < HFIXEDSZ || qlen >= (1 << 16))
+    {
+      callback(arg, ARES_EBADQUERY, 0, NULL, 0);
+      return;
+    }
+
+  /* Allocate space for query and allocated fields. */
+  query = malloc(sizeof(struct query));
+  if (!query)
+    {
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+  query->tcpbuf = malloc(qlen + 2);
+  if (!query->tcpbuf)
+    {
+      free(query);
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+  query->server_info = malloc(channel->nservers *
+                              sizeof(query->server_info[0]));
+  if (!query->server_info)
+    {
+      free(query->tcpbuf);
+      free(query);
+      callback(arg, ARES_ENOMEM, 0, NULL, 0);
+      return;
+    }
+
+  /* Compute the query ID.  Start with no timeout. */
+  query->qid = (unsigned short)DNS_HEADER_QID(qbuf);
+  query->timeout.tv_sec = 0;
+  query->timeout.tv_usec = 0;
+
+  /* Form the TCP query buffer by prepending qlen (as two
+   * network-order bytes) to qbuf.
+   */
+  query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff);
+  query->tcpbuf[1] = (unsigned char)(qlen & 0xff);
+  memcpy(query->tcpbuf + 2, qbuf, qlen);
+  query->tcplen = qlen + 2;
+
+  /* Fill in query arguments. */
+  query->qbuf = query->tcpbuf + 2;
+  query->qlen = qlen;
+  query->callback = callback;
+  query->arg = arg;
+
+  /* Initialize query status. */
+  query->try = 0;
+
+  /* Choose the server to send the query to. If rotation is enabled, keep track
+   * of the next server we want to use. */
+  query->server = channel->last_server;
+  if (channel->rotate == 1)
+    channel->last_server = (channel->last_server + 1) % channel->nservers;
+
+  for (i = 0; i < channel->nservers; i++)
+    {
+      query->server_info[i].skip_server = 0;
+      query->server_info[i].tcp_connection_generation = 0;
+    }
+  query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ;
+  query->error_status = ARES_ECONNREFUSED;
+  query->timeouts = 0;
+
+  /* Initialize our list nodes. */
+  ares__init_list_node(&(query->queries_by_qid),     query);
+  ares__init_list_node(&(query->queries_by_timeout), query);
+  ares__init_list_node(&(query->queries_to_server),  query);
+  ares__init_list_node(&(query->all_queries),        query);
+
+  /* Chain the query into the list of all queries. */
+  ares__insert_in_list(&(query->all_queries), &(channel->all_queries));
+  /* Keep track of queries bucketed by qid, so we can process DNS
+   * responses quickly.
+   */
+  ares__insert_in_list(
+    &(query->queries_by_qid),
+    &(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE]));
+
+  /* Perform the first query action. */
+  now = ares__tvnow();
+  ares__send_query(channel, query, &now);
+}
diff --git a/3rdParty/CAres/src/ares_setup.h b/3rdParty/CAres/src/ares_setup.h
new file mode 100644
index 0000000..5ce9398
--- /dev/null
+++ b/3rdParty/CAres/src/ares_setup.h
@@ -0,0 +1,198 @@
+#ifndef HEADER_CARES_SETUP_H
+#define HEADER_CARES_SETUP_H
+
+/* $Id: ares_setup.h,v 1.2 2009-11-14 18:51:37 yangtse Exp $ */
+
+/* Copyright (C) 2004 - 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#define WIN32
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "ares_config.h"
+#else
+
+#ifdef WIN32
+#include "config-win32.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler  */
+/* behaviour or generated code characteristics must be done here,   */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included   */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+#  ifndef _THREAD_SAFE
+#    define _THREAD_SAFE
+#  endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+#  ifndef _REENTRANT
+#    define _REENTRANT
+#  endif
+#endif
+
+/* ================================================================ */
+/*  If you need to include a system header file for your platform,  */
+/*  please, do it beyond the point further indicated in this file.  */
+/* ================================================================ */
+
+/*
+ * c-ares external interface definitions are also used internally,
+ * and might also include required system header files to define them.
+ */
+
+#include <ares_build.h>
+
+/*
+ * Compile time sanity checks must also be done when building the library.
+ */
+
+#include <ares_rules.h>
+
+/* ================================================================= */
+/* No system header file shall be included in this file before this  */
+/* point. The only allowed ones are those included from ares_build.h */
+/* ================================================================= */
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preproessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#       include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+/*
+ * Work-arounds for systems without configure support
+ */
+
+#ifndef HAVE_CONFIG_H
+
+#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
+#define HAVE_SYS_TIME_H
+#endif
+
+#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
+#define HAVE_UNISTD_H 1
+#endif
+
+#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
+#define HAVE_SYS_UIO_H
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __POCC__
+#  include <sys/types.h>
+#  include <unistd.h>
+#  define ESRCH 3
+#endif
+
+/*
+ * Recent autoconf versions define these symbols in ares_config.h. We don't
+ * want them (since they collide with the libcurl ones when we build
+ *  --enable-debug) so we undef them again here.
+ */
+
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef VERSION
+#undef PACKAGE
+
+/* IPv6 compatibility */
+#if !defined(HAVE_AF_INET6)
+#if defined(HAVE_PF_INET6)
+#define AF_INET6 PF_INET6
+#else
+#define AF_INET6 AF_MAX+1
+#endif
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef __SETUP_ONCE_H
+#include "setup_once.h"
+#endif
+
+#endif /* HEADER_CARES_SETUP_H */
diff --git a/3rdParty/CAres/src/ares_strcasecmp.c b/3rdParty/CAres/src/ares_strcasecmp.c
new file mode 100644
index 0000000..8329e30
--- /dev/null
+++ b/3rdParty/CAres/src/ares_strcasecmp.c
@@ -0,0 +1,67 @@
+
+/* $Id: ares_strcasecmp.c,v 1.2 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares_strcasecmp.h"
+
+#ifndef HAVE_STRCASECMP
+int ares_strcasecmp(const char *a, const char *b)
+{
+#if defined(HAVE_STRCMPI)
+  return strcmpi(a, b);
+#elif defined(HAVE_STRICMP)
+  return stricmp(a, b);
+#else
+  size_t i;
+
+  for (i = 0; i < (size_t)-1; i++) {
+    int c1 = ISUPPER(a[i]) ? tolower(a[i]) : a[i];
+    int c2 = ISUPPER(b[i]) ? tolower(b[i]) : b[i];
+    if (c1 != c2)
+      return c1-c2;
+    if (!c1)
+      break;
+  }
+  return 0;
+#endif
+}
+#endif
+
+#ifndef HAVE_STRNCASECMP
+int ares_strncasecmp(const char *a, const char *b, size_t n)
+{
+#if defined(HAVE_STRNCMPI)
+  return strncmpi(a, b, n);
+#elif defined(HAVE_STRNICMP)
+  return strnicmp(a, b, n);
+#else
+  size_t i;
+
+  for (i = 0; i < n; i++) {
+    int c1 = ISUPPER(a[i]) ? tolower(a[i]) : a[i];
+    int c2 = ISUPPER(b[i]) ? tolower(b[i]) : b[i];
+    if (c1 != c2)
+      return c1-c2;
+    if (!c1)
+      break;
+  }
+  return 0;
+#endif
+}
+#endif
+
diff --git a/3rdParty/CAres/src/ares_strcasecmp.h b/3rdParty/CAres/src/ares_strcasecmp.h
new file mode 100644
index 0000000..db170be
--- /dev/null
+++ b/3rdParty/CAres/src/ares_strcasecmp.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CARES_STRCASECMP_H
+#define HEADER_CARES_STRCASECMP_H
+
+/* $Id: ares_strcasecmp.h,v 1.2 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifndef HAVE_STRCASECMP
+extern int ares_strcasecmp(const char *a, const char *b);
+#endif
+
+#ifndef HAVE_STRNCASECMP
+extern int ares_strncasecmp(const char *a, const char *b, size_t n);
+#endif
+
+#endif /* HEADER_CARES_STRCASECMP_H */
diff --git a/3rdParty/CAres/src/ares_strdup.c b/3rdParty/CAres/src/ares_strdup.c
new file mode 100644
index 0000000..d3f2b22
--- /dev/null
+++ b/3rdParty/CAres/src/ares_strdup.c
@@ -0,0 +1,43 @@
+
+/* $Id: ares_strdup.c,v 1.3 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares_strdup.h"
+
+#ifndef HAVE_STRDUP
+char *ares_strdup(const char *s1)
+{
+  size_t sz;
+  char * s2;
+
+  if(s1) {
+    sz = strlen(s1);
+    if(sz < (size_t)-1) {
+      sz++;
+      if(sz < ((size_t)-1) / sizeof(char)) {
+        s2 = malloc(sz * sizeof(char));
+        if(s2) {
+          memcpy(s2, s1, sz * sizeof(char));
+          return s2;
+        }
+      }
+    }
+  }
+  return (char *)NULL;
+}
+#endif
diff --git a/3rdParty/CAres/src/ares_strdup.h b/3rdParty/CAres/src/ares_strdup.h
new file mode 100644
index 0000000..f88f8d1
--- /dev/null
+++ b/3rdParty/CAres/src/ares_strdup.h
@@ -0,0 +1,27 @@
+#ifndef HEADER_CARES_STRDUP_H
+#define HEADER_CARES_STRDUP_H
+
+/* $Id: ares_strdup.h,v 1.3 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifndef HAVE_STRDUP
+extern char *ares_strdup(const char *s1);
+#endif
+
+#endif /* HEADER_CARES_STRDUP_H */
diff --git a/3rdParty/CAres/src/ares_strerror.c b/3rdParty/CAres/src/ares_strerror.c
new file mode 100644
index 0000000..57fcf8f
--- /dev/null
+++ b/3rdParty/CAres/src/ares_strerror.c
@@ -0,0 +1,57 @@
+/* $Id: ares_strerror.c,v 1.18 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include <assert.h>
+#include "ares.h"
+
+const char *ares_strerror(int code)
+{
+  /* Return a string literal from a table. */
+  const char *errtext[] = {
+    "Successful completion",
+    "DNS server returned answer with no data",
+    "DNS server claims query was misformatted",
+    "DNS server returned general failure",
+    "Domain name not found",
+    "DNS server does not implement requested operation",
+    "DNS server refused query",
+    "Misformatted DNS query",
+    "Misformatted domain name",
+    "Unsupported address family",
+    "Misformatted DNS reply",
+    "Could not contact DNS servers",
+    "Timeout while contacting DNS servers",
+    "End of file",
+    "Error reading file",
+    "Out of memory",
+    "Channel is being destroyed",
+    "Misformatted string",
+    "Illegal flags specified",
+    "Given hostname is not numeric",
+    "Illegal hints flags specified",
+    "c-ares library initialization not yet performed",
+    "Error loading iphlpapi.dll",
+    "Could not find GetNetworkParams function",
+    "DNS query cancelled"
+  };
+
+  if(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)))
+    return errtext[code];
+  else
+    return "unknown";
+}
diff --git a/3rdParty/CAres/src/ares_timeout.c b/3rdParty/CAres/src/ares_timeout.c
new file mode 100644
index 0000000..a522de7
--- /dev/null
+++ b/3rdParty/CAres/src/ares_timeout.c
@@ -0,0 +1,81 @@
+/* $Id: ares_timeout.c,v 1.13 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+
+#include "ares.h"
+#include "ares_private.h"
+
+/* WARNING: Beware that this is linear in the number of outstanding
+ * requests! You are probably far better off just calling ares_process()
+ * once per second, rather than calling ares_timeout() to figure out
+ * when to next call ares_process().
+ */
+struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
+                             struct timeval *tvbuf)
+{
+  struct query *query;
+  struct list_node* list_head;
+  struct list_node* list_node;
+  struct timeval now;
+  struct timeval nextstop;
+  long offset, min_offset;
+
+  /* No queries, no timeout (and no fetch of the current time). */
+  if (ares__is_list_empty(&(channel->all_queries)))
+    return maxtv;
+
+  /* Find the minimum timeout for the current set of queries. */
+  now = ares__tvnow();
+  min_offset = -1;
+
+  list_head = &(channel->all_queries);
+  for (list_node = list_head->next; list_node != list_head;
+       list_node = list_node->next)
+    {
+      query = list_node->data;
+      if (query->timeout.tv_sec == 0)
+        continue;
+      offset = ares__timeoffset(&now, &query->timeout);
+      if (offset < 0)
+        offset = 0;
+      if (min_offset == -1 || offset < min_offset)
+        min_offset = offset;
+    }
+
+  if(min_offset != -1) {
+    nextstop.tv_sec = min_offset/1000;
+    nextstop.tv_usec = (min_offset%1000)*1000;
+  }
+
+  /* If we found a minimum timeout and it's sooner than the one specified in
+   * maxtv (if any), return it.  Otherwise go with maxtv.
+   */
+  if (min_offset != -1 && (!maxtv || ares__timedout(maxtv, &nextstop)))
+    {
+      *tvbuf = nextstop;
+      return tvbuf;
+    }
+  else
+    return maxtv;
+}
diff --git a/3rdParty/CAres/src/ares_version.c b/3rdParty/CAres/src/ares_version.c
new file mode 100644
index 0000000..3007150
--- /dev/null
+++ b/3rdParty/CAres/src/ares_version.c
@@ -0,0 +1,12 @@
+/* $Id: ares_version.c,v 1.5 2009-11-02 11:55:53 yangtse Exp $ */
+
+#include "ares_setup.h"
+#include "ares.h"
+
+const char *ares_version(int *version)
+{
+  if(version)
+    *version = ARES_VERSION;
+
+  return ARES_VERSION_STR;
+}
diff --git a/3rdParty/CAres/src/ares_version.h b/3rdParty/CAres/src/ares_version.h
new file mode 100644
index 0000000..d3a6295
--- /dev/null
+++ b/3rdParty/CAres/src/ares_version.h
@@ -0,0 +1,22 @@
+/* $Id: ares_version.h,v 1.19 2009-11-23 12:03:33 yangtse Exp $ */
+
+#ifndef ARES__VERSION_H
+#define ARES__VERSION_H
+
+#define ARES_VERSION_MAJOR 1
+#define ARES_VERSION_MINOR 7
+#define ARES_VERSION_PATCH 0
+#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
+                       (ARES_VERSION_MINOR<<8)|\
+                       (ARES_VERSION_PATCH))
+#define ARES_VERSION_STR "1.7.0"
+
+#if (ARES_VERSION >= 0x010700)
+#  define CARES_HAVE_ARES_LIBRARY_INIT 1
+#  define CARES_HAVE_ARES_LIBRARY_CLEANUP 1
+#else
+#  undef CARES_HAVE_ARES_LIBRARY_INIT
+#  undef CARES_HAVE_ARES_LIBRARY_CLEANUP
+#endif
+
+#endif
diff --git a/3rdParty/CAres/src/ares_writev.c b/3rdParty/CAres/src/ares_writev.c
new file mode 100644
index 0000000..855ce14
--- /dev/null
+++ b/3rdParty/CAres/src/ares_writev.c
@@ -0,0 +1,80 @@
+
+/* $Id: ares_writev.c,v 1.3 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+#ifndef HAVE_WRITEV
+ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
+{
+  char *buffer, *bp;
+  int i;
+  size_t bytes = 0;
+  ssize_t result;
+
+  /* Validate iovcnt */
+  if (iovcnt <= 0)
+  {
+    SET_ERRNO(EINVAL);
+    return (-1);
+  }
+
+  /* Validate and find the sum of the iov_len values in the iov array */
+  for (i = 0; i < iovcnt; i++)
+  {
+    if (iov[i].iov_len > INT_MAX - bytes)
+    {
+      SET_ERRNO(EINVAL);
+      return (-1);
+    }
+    bytes += iov[i].iov_len;
+  }
+
+  if (bytes == 0)
+    return (0);
+
+  /* Allocate a temporary buffer to hold the data */
+  buffer = malloc(bytes);
+  if (!buffer)
+  {
+    SET_ERRNO(ENOMEM);
+    return (-1);
+  }
+
+  /* Copy the data into buffer */
+  for (bp = buffer, i = 0; i < iovcnt; ++i)
+  {
+    memcpy (bp, iov[i].iov_base, iov[i].iov_len);
+    bp += iov[i].iov_len;
+  }
+
+  /* Send buffer contents */
+  result = swrite(s, buffer, bytes);
+
+  free(buffer);
+
+  return (result);
+}
+#endif
+
diff --git a/3rdParty/CAres/src/ares_writev.h b/3rdParty/CAres/src/ares_writev.h
new file mode 100644
index 0000000..631baf8
--- /dev/null
+++ b/3rdParty/CAres/src/ares_writev.h
@@ -0,0 +1,37 @@
+#ifndef HEADER_CARES_WRITEV_H
+#define HEADER_CARES_WRITEV_H
+
+/* $Id: ares_writev.h,v 1.2 2009-11-02 11:55:53 yangtse Exp $ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares.h"
+
+#ifndef HAVE_WRITEV
+
+/* Structure for scatter/gather I/O. */
+struct iovec
+{
+  void *iov_base;  /* Pointer to data. */
+  size_t iov_len;  /* Length of data.  */
+};
+
+extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt);
+
+#endif
+
+#endif /* HEADER_CARES_WRITEV_H */
diff --git a/3rdParty/CAres/src/bitncmp.c b/3rdParty/CAres/src/bitncmp.c
new file mode 100644
index 0000000..f36ffaa
--- /dev/null
+++ b/3rdParty/CAres/src/bitncmp.c
@@ -0,0 +1,60 @@
+/* $Id: bitncmp.c,v 1.8 2009-11-02 11:55:54 yangtse Exp $ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef HAVE_BITNCMP
+
+#include "ares_setup.h"
+#include "bitncmp.h"
+
+/*
+ * int
+ * bitncmp(l, r, n)
+ *	compare bit masks l and r, for n bits.
+ * return:
+ *	-1, 1, or 0 in the libc tradition.
+ * note:
+ *	network byte order assumed.  this means 192.5.5.240/28 has
+ *	0x11110000 in its fourth octet.
+ * author:
+ *	Paul Vixie (ISC), June 1996
+ */
+int
+ares_bitncmp(const void *l, const void *r, int n) {
+	unsigned int lb, rb;
+	int x, b;
+
+	b = n / 8;
+	x = memcmp(l, r, b);
+	if (x || (n % 8) == 0)
+		return (x);
+
+	lb = ((const unsigned char *)l)[b];
+	rb = ((const unsigned char *)r)[b];
+	for (b = n % 8; b > 0; b--) {
+		if ((lb & 0x80) != (rb & 0x80)) {
+			if (lb & 0x80)
+				return (1);
+			return (-1);
+		}
+		lb <<= 1;
+		rb <<= 1;
+	}
+	return (0);
+}
+#endif
diff --git a/3rdParty/CAres/src/bitncmp.h b/3rdParty/CAres/src/bitncmp.h
new file mode 100644
index 0000000..4805683
--- /dev/null
+++ b/3rdParty/CAres/src/bitncmp.h
@@ -0,0 +1,27 @@
+#ifndef __ARES_BITNCMP_H
+#define __ARES_BITNCMP_H
+
+/* $Id: bitncmp.h,v 1.3 2007-11-19 15:47:01 bagder Exp $ */
+
+/* Copyright (C) 2005 by Dominick Meglio
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef HAVE_BITNCMP
+int ares_bitncmp(const void *l, const void *r, int n);
+#else
+#define ares_bitncmp(x,y,z) bitncmp(x,y,z)
+#endif
+
+#endif /* __ARES_BITNCMP_H */
diff --git a/3rdParty/CAres/src/config-win32.h b/3rdParty/CAres/src/config-win32.h
new file mode 100644
index 0000000..295df81
--- /dev/null
+++ b/3rdParty/CAres/src/config-win32.h
@@ -0,0 +1,341 @@
+#ifndef __ARES_CONFIG_WIN32_H
+#define __ARES_CONFIG_WIN32_H
+
+/* $Id: config-win32.h,v 1.32 2009-10-27 16:38:42 yangtse Exp $ */
+
+/* Copyright (C) 2004 - 2008 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/*    ares/config-win32.h - Hand crafted config file for Windows    */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/*                          HEADER FILES                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the <getopt.h> header file.  */
+#if defined(__MINGW32__) || defined(__POCC__)
+#define HAVE_GETOPT_H 1
+#endif
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <process.h> header file.  */
+#ifndef __SALFORDC__
+#define HAVE_PROCESS_H 1
+#endif
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <sys/time.h> header file */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <time.h> header file.  */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
+    defined(__POCC__)
+#define HAVE_UNISTD_H 1
+#endif
+
+/* Define if you have the <windows.h> header file.  */
+#define HAVE_WINDOWS_H 1
+
+/* Define if you have the <winsock.h> header file.  */
+#define HAVE_WINSOCK_H 1
+
+/* Define if you have the <winsock2.h> header file.  */
+#ifndef __SALFORDC__
+#define HAVE_WINSOCK2_H 1
+#endif
+
+/* Define if you have the <ws2tcpip.h> header file.  */
+#ifndef __SALFORDC__
+#define HAVE_WS2TCPIP_H 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                        OTHER HEADER INFO                         */
+/* ---------------------------------------------------------------- */
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* ---------------------------------------------------------------- */
+/*                             FUNCTIONS                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the gethostname function.  */
+#define HAVE_GETHOSTNAME 1
+
+/* Define if you have the ioctlsocket function. */
+#define HAVE_IOCTLSOCKET 1
+
+/* Define if you have a working ioctlsocket FIONBIO function. */
+#define HAVE_IOCTLSOCKET_FIONBIO 1
+
+/* Define if you have the strcasecmp function. */
+/* #define HAVE_STRCASECMP 1 */
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the stricmp function. */
+#define HAVE_STRICMP 1
+
+/* Define if you have the strncasecmp function. */
+/* #define HAVE_STRNCASECMP 1 */
+
+/* Define if you have the strnicmp function. */
+#define HAVE_STRNICMP 1
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 SOCKET
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 SOCKET
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 SOCKET
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* Specifics for the Watt-32 tcp/ip stack */
+#ifdef WATT32
+  #define SOCKET              int
+  #define NS_INADDRSZ         4
+  #define HAVE_ARPA_NAMESER_H 1
+  #define HAVE_ARPA_INET_H    1
+  #define HAVE_NETDB_H        1
+  #define HAVE_NETINET_IN_H   1
+  #define HAVE_SYS_SOCKET_H   1
+  #define HAVE_NETINET_TCP_H  1
+  #define HAVE_AF_INET6       1
+  #define HAVE_PF_INET6       1
+  #define HAVE_STRUCT_IN6_ADDR     1
+  #define HAVE_STRUCT_SOCKADDR_IN6 1
+  #undef HAVE_WINSOCK_H
+  #undef HAVE_WINSOCK2_H
+  #undef HAVE_WS2TCPIP_H
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                       TYPEDEF REPLACEMENTS                       */
+/* ---------------------------------------------------------------- */
+
+/* Define this if in_addr_t is not an available 'typedefed' type */
+#define in_addr_t unsigned long
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define ssize_t if it is not an available 'typedefed' type */
+#ifndef _SSIZE_T_DEFINED
+#  if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
+      defined(__POCC__) || \
+      defined(__MINGW32__)
+#  elif defined(_WIN64)
+#    define _SSIZE_T_DEFINED
+#    define ssize_t __int64
+#  else
+#    define _SSIZE_T_DEFINED
+#    define ssize_t int
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                          STRUCT RELATED                          */
+/* ---------------------------------------------------------------- */
+
+/* Define this if you have struct addrinfo */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define this if you have struct sockaddr_storage */
+#ifndef __SALFORDC__
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+/* Define this if you have struct timeval */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* ---------------------------------------------------------------- */
+/*                        COMPILER SPECIFIC                         */
+/* ---------------------------------------------------------------- */
+
+/* Define to avoid VS2005 complaining about portable C functions */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
+   2000 as a supported build target. VS2008 default installations provide an
+   embedded Windows SDK v6.0A along with the claim that Windows 2000 is a
+   valid build target for VS2008. Popular belief is that binaries built using
+   Windows SDK versions 6.X and Windows 2000 as a build target are functional */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#  define VS2008_MINIMUM_TARGET 0x0500
+#endif
+
+/* When no build target is specified VS2008 default build target is Windows
+   Vista, which leaves out even Winsows XP. If no build target has been given
+   for VS2008 we will target the minimum Officially supported build target,
+   which happens to be Windows XP. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#  define VS2008_DEFAULT_TARGET  0x0501
+#endif
+
+/* VS2008 default target settings and minimum build target check */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT VS2008_DEFAULT_TARGET
+#  endif
+#  ifndef WINVER
+#    define WINVER VS2008_DEFAULT_TARGET
+#  endif
+#  if (_WIN32_WINNT < VS2008_MINIMUM_TARGET) || (WINVER < VS2008_MINIMUM_TARGET)
+#    error VS2008 does not support Windows build targets prior to Windows 2000
+#  endif
+#endif
+
+/* When no build target is specified Pelles C 5.00 and later default build
+   target is Windows Vista. We override default target to be Windows 2000. */
+#if defined(__POCC__) && (__POCC__ >= 500)
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT 0x0500
+#  endif
+#  ifndef WINVER
+#    define WINVER 0x0500
+#  endif
+#endif
+
+/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is
+   quite convoluted, compiler dependent and even build target dependent. */
+#if defined(HAVE_WS2TCPIP_H)
+#  if defined(__POCC__)
+#    define HAVE_FREEADDRINFO 1
+#    define HAVE_GETADDRINFO  1
+#    define HAVE_GETNAMEINFO  1
+#  elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
+#    define HAVE_FREEADDRINFO 1
+#    define HAVE_GETADDRINFO  1
+#    define HAVE_GETNAMEINFO  1
+#  elif defined(_MSC_VER) && (_MSC_VER >= 1200)
+#    define HAVE_FREEADDRINFO 1
+#    define HAVE_GETADDRINFO  1
+#    define HAVE_GETNAMEINFO  1
+#  endif
+#endif
+
+#if defined(__POCC__)
+#  ifndef _MSC_VER
+#    error Microsoft extensions /Ze compiler option is required
+#  endif
+#  ifndef __POCC__OLDNAMES
+#    error Compatibility names /Go compiler option is required
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                         IPV6 COMPATIBILITY                       */
+/* ---------------------------------------------------------------- */
+
+/* Define this if you have address family AF_INET6 */
+#ifdef HAVE_WINSOCK2_H
+#define HAVE_AF_INET6 1
+#endif
+
+/* Define this if you have protocol family PF_INET6 */
+#ifdef HAVE_WINSOCK2_H
+#define HAVE_PF_INET6 1
+#endif
+
+/* Define this if you have struct in6_addr */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_STRUCT_IN6_ADDR 1
+#endif
+
+/* Define this if you have struct sockaddr_in6 */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+/* Define this if you have sockaddr_in6 with scopeid */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+#endif
+
+
+#endif  /* __ARES_CONFIG_WIN32_H */
diff --git a/3rdParty/CAres/src/inet_net_pton.c b/3rdParty/CAres/src/inet_net_pton.c
new file mode 100644
index 0000000..de09ace
--- /dev/null
+++ b/3rdParty/CAres/src/inet_net_pton.c
@@ -0,0 +1,446 @@
+/* $Id: inet_net_pton.c,v 1.17 2009-11-02 11:55:54 yangtse Exp $ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ares_ipv6.h"
+#include "inet_net_pton.h"
+
+#if !defined(HAVE_INET_NET_PTON) || !defined(HAVE_INET_NET_PTON_IPV6)
+
+/*
+ * static int
+ * inet_net_pton_ipv4(src, dst, size)
+ *      convert IPv4 network number from presentation to network format.
+ *      accepts hex octets, hex strings, decimal octets, and /CIDR.
+ *      "size" is in bytes and describes "dst".
+ * return:
+ *      number of bits, either imputed classfully or specified with /CIDR,
+ *      or -1 if some failure occurred (check errno).  ENOENT means it was
+ *      not an IPv4 network specification.
+ * note:
+ *      network byte order assumed.  this means 192.5.5.240/28 has
+ *      0b11110000 in its fourth octet.
+ * note:
+ *      On Windows we store the error in the thread errno, not
+ *      in the winsock error code. This is to avoid loosing the
+ *      actual last winsock error. So use macro ERRNO to fetch the
+ *      errno this funtion sets when returning (-1), not SOCKERRNO.
+ * author:
+ *      Paul Vixie (ISC), June 1996
+ */
+static int
+inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
+{
+  static const char xdigits[] = "0123456789abcdef";
+  static const char digits[] = "0123456789";
+  int n, ch, tmp = 0, dirty, bits;
+  const unsigned char *odst = dst;
+
+  ch = *src++;
+  if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
+      && ISXDIGIT(src[1])) {
+    /* Hexadecimal: Eat nybble string. */
+    if (!size)
+      goto emsgsize;
+    dirty = 0;
+    src++;  /* skip x or X. */
+    while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
+      if (ISUPPER(ch))
+        ch = tolower(ch);
+      n = (int)(strchr(xdigits, ch) - xdigits);
+      if (dirty == 0)
+        tmp = n;
+      else
+        tmp = (tmp << 4) | n;
+      if (++dirty == 2) {
+        if (!size--)
+          goto emsgsize;
+        *dst++ = (unsigned char) tmp;
+        dirty = 0;
+      }
+    }
+    if (dirty) {  /* Odd trailing nybble? */
+      if (!size--)
+        goto emsgsize;
+      *dst++ = (unsigned char) (tmp << 4);
+    }
+  } else if (ISDIGIT(ch)) {
+    /* Decimal: eat dotted digit string. */
+    for (;;) {
+      tmp = 0;
+      do {
+        n = (int)(strchr(digits, ch) - digits);
+        tmp *= 10;
+        tmp += n;
+        if (tmp > 255)
+          goto enoent;
+      } while ((ch = *src++) != '\0' &&
+               ISDIGIT(ch));
+      if (!size--)
+        goto emsgsize;
+      *dst++ = (unsigned char) tmp;
+      if (ch == '\0' || ch == '/')
+        break;
+      if (ch != '.')
+        goto enoent;
+      ch = *src++;
+      if (!ISDIGIT(ch))
+        goto enoent;
+    }
+  } else
+    goto enoent;
+
+  bits = -1;
+  if (ch == '/' &&
+      ISDIGIT(src[0]) && dst > odst) {
+    /* CIDR width specifier.  Nothing can follow it. */
+    ch = *src++;    /* Skip over the /. */
+    bits = 0;
+    do {
+      n = (int)(strchr(digits, ch) - digits);
+      bits *= 10;
+      bits += n;
+    } while ((ch = *src++) != '\0' && ISDIGIT(ch));
+    if (ch != '\0')
+      goto enoent;
+    if (bits > 32)
+      goto emsgsize;
+  }
+
+  /* Firey death and destruction unless we prefetched EOS. */
+  if (ch != '\0')
+    goto enoent;
+
+  /* If nothing was written to the destination, we found no address. */
+  if (dst == odst)
+    goto enoent;
+  /* If no CIDR spec was given, infer width from net class. */
+  if (bits == -1) {
+    if (*odst >= 240)       /* Class E */
+      bits = 32;
+    else if (*odst >= 224)  /* Class D */
+      bits = 8;
+    else if (*odst >= 192)  /* Class C */
+      bits = 24;
+    else if (*odst >= 128)  /* Class B */
+      bits = 16;
+    else                    /* Class A */
+      bits = 8;
+    /* If imputed mask is narrower than specified octets, widen. */
+    if (bits < ((dst - odst) * 8))
+      bits = (int)(dst - odst) * 8;
+    /*
+     * If there are no additional bits specified for a class D
+     * address adjust bits to 4.
+     */
+    if (bits == 8 && *odst == 224)
+      bits = 4;
+  }
+  /* Extend network to cover the actual mask. */
+  while (bits > ((dst - odst) * 8)) {
+    if (!size--)
+      goto emsgsize;
+    *dst++ = '\0';
+  }
+  return (bits);
+
+  enoent:
+  SET_ERRNO(ENOENT);
+  return (-1);
+
+  emsgsize:
+  SET_ERRNO(EMSGSIZE);
+  return (-1);
+}
+
+static int
+getbits(const char *src, int *bitsp)
+{
+  static const char digits[] = "0123456789";
+  int n;
+  int val;
+  char ch;
+
+  val = 0;
+  n = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
+
+    pch = strchr(digits, ch);
+    if (pch != NULL) {
+      if (n++ != 0 && val == 0)       /* no leading zeros */
+        return (0);
+      val *= 10;
+      val += (pch - digits);
+      if (val > 128)                  /* range */
+        return (0);
+      continue;
+    }
+    return (0);
+  }
+  if (n == 0)
+    return (0);
+  *bitsp = val;
+  return (1);
+}
+
+static int
+getv4(const char *src, unsigned char *dst, int *bitsp)
+{
+  static const char digits[] = "0123456789";
+  unsigned char *odst = dst;
+  int n;
+  unsigned int val;
+  char ch;
+
+  val = 0;
+  n = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
+
+    pch = strchr(digits, ch);
+    if (pch != NULL) {
+      if (n++ != 0 && val == 0)       /* no leading zeros */
+        return (0);
+      val *= 10;
+      val += (pch - digits);
+      if (val > 255)                  /* range */
+        return (0);
+      continue;
+    }
+    if (ch == '.' || ch == '/') {
+      if (dst - odst > 3)             /* too many octets? */
+        return (0);
+      *dst++ = (unsigned char)val;
+      if (ch == '/')
+        return (getbits(src, bitsp));
+      val = 0;
+      n = 0;
+      continue;
+    }
+    return (0);
+  }
+  if (n == 0)
+    return (0);
+  if (dst - odst > 3)             /* too many octets? */
+    return (0);
+  *dst++ = (unsigned char)val;
+  return (1);
+}
+
+static int
+inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
+{
+  static const char xdigits_l[] = "0123456789abcdef",
+    xdigits_u[] = "0123456789ABCDEF";
+  unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *xdigits, *curtok;
+  int ch, saw_xdigit;
+  unsigned int val;
+  int digits;
+  int bits;
+  size_t bytes;
+  int words;
+  int ipv4;
+
+  memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+  endp = tp + NS_IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if (*src == ':')
+    if (*++src != ':')
+      goto enoent;
+  curtok = src;
+  saw_xdigit = 0;
+  val = 0;
+  digits = 0;
+  bits = -1;
+  ipv4 = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
+
+    if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if (pch != NULL) {
+      val <<= 4;
+      val |= (pch - xdigits);
+      if (++digits > 4)
+        goto enoent;
+      saw_xdigit = 1;
+      continue;
+    }
+    if (ch == ':') {
+      curtok = src;
+      if (!saw_xdigit) {
+        if (colonp)
+          goto enoent;
+        colonp = tp;
+        continue;
+      } else if (*src == '\0')
+        goto enoent;
+      if (tp + NS_INT16SZ > endp)
+        return (0);
+      *tp++ = (unsigned char)((val >> 8) & 0xff);
+      *tp++ = (unsigned char)(val & 0xff);
+      saw_xdigit = 0;
+      digits = 0;
+      val = 0;
+      continue;
+    }
+    if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+        getv4(curtok, tp, &bits) > 0) {
+      tp += NS_INADDRSZ;
+      saw_xdigit = 0;
+      ipv4 = 1;
+      break;  /* '\0' was seen by inet_pton4(). */
+    }
+    if (ch == '/' && getbits(src, &bits) > 0)
+      break;
+    goto enoent;
+  }
+  if (saw_xdigit) {
+    if (tp + NS_INT16SZ > endp)
+      goto enoent;
+    *tp++ = (unsigned char)((val >> 8) & 0xff);
+    *tp++ = (unsigned char)(val & 0xff);
+  }
+  if (bits == -1)
+    bits = 128;
+
+  words = (bits + 15) / 16;
+  if (words < 2)
+    words = 2;
+  if (ipv4)
+    words = 8;
+  endp =  tmp + 2 * words;
+
+  if (colonp != NULL) {
+    /*
+     * Since some memmove()'s erroneously fail to handle
+     * overlapping regions, we'll do the shift by hand.
+     */
+    const int n = (int)(tp - colonp);
+    int i;
+
+    if (tp == endp)
+      goto enoent;
+    for (i = 1; i <= n; i++) {
+      endp[- i] = colonp[n - i];
+      colonp[n - i] = 0;
+    }
+    tp = endp;
+  }
+  if (tp != endp)
+    goto enoent;
+
+  bytes = (bits + 7) / 8;
+  if (bytes > size)
+    goto emsgsize;
+  memcpy(dst, tmp, bytes);
+  return (bits);
+
+  enoent:
+  SET_ERRNO(ENOENT);
+  return (-1);
+
+  emsgsize:
+  SET_ERRNO(EMSGSIZE);
+  return (-1);
+}
+
+/*
+ * int
+ * inet_net_pton(af, src, dst, size)
+ *      convert network number from presentation to network format.
+ *      accepts hex octets, hex strings, decimal octets, and /CIDR.
+ *      "size" is in bytes and describes "dst".
+ * return:
+ *      number of bits, either imputed classfully or specified with /CIDR,
+ *      or -1 if some failure occurred (check errno).  ENOENT means it was
+ *      not a valid network specification.
+ * note:
+ *      On Windows we store the error in the thread errno, not
+ *      in the winsock error code. This is to avoid loosing the
+ *      actual last winsock error. So use macro ERRNO to fetch the
+ *      errno this funtion sets when returning (-1), not SOCKERRNO.
+ * author:
+ *      Paul Vixie (ISC), June 1996
+ */
+int
+ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
+{
+  switch (af) {
+  case AF_INET:
+    return (inet_net_pton_ipv4(src, dst, size));
+  case AF_INET6:
+    return (inet_net_pton_ipv6(src, dst, size));
+  default:
+    SET_ERRNO(EAFNOSUPPORT);
+    return (-1);
+  }
+}
+
+#endif
+
+#ifndef HAVE_INET_PTON
+int ares_inet_pton(int af, const char *src, void *dst)
+{
+  int result;
+  size_t size;
+
+  if (af == AF_INET)
+    size = sizeof(struct in_addr);
+  else if (af == AF_INET6)
+    size = sizeof(struct in6_addr);
+  else
+  {
+    SET_ERRNO(EAFNOSUPPORT);
+    return -1;
+  }
+  result = ares_inet_net_pton(af, src, dst, size);
+  if (result == -1 && ERRNO == ENOENT)
+    return 0;
+  return (result > -1 ? 1 : -1);
+}
+#endif
diff --git a/3rdParty/CAres/src/inet_net_pton.h b/3rdParty/CAres/src/inet_net_pton.h
new file mode 100644
index 0000000..eb38afa
--- /dev/null
+++ b/3rdParty/CAres/src/inet_net_pton.h
@@ -0,0 +1,32 @@
+#ifndef __ARES_INET_NET_PTON_H
+#define __ARES_INET_NET_PTON_H
+
+/* $Id: inet_net_pton.h,v 1.6 2008-09-24 19:13:02 yangtse Exp $ */
+
+/* Copyright (C) 2005 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifdef HAVE_INET_PTON
+#define ares_inet_pton(x,y,z) inet_pton(x,y,z)
+#else
+int ares_inet_pton(int af, const char *src, void *dst);
+#endif
+#if defined(HAVE_INET_NET_PTON) && defined(HAVE_INET_NET_PTON_IPV6)
+#define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z)
+#else
+int ares_inet_net_pton(int af, const char *src, void *dst, size_t size);
+#endif
+
+#endif /* __ARES_INET_NET_PTON_H */
diff --git a/3rdParty/CAres/src/inet_ntop.c b/3rdParty/CAres/src/inet_ntop.c
new file mode 100644
index 0000000..5b0d097
--- /dev/null
+++ b/3rdParty/CAres/src/inet_ntop.c
@@ -0,0 +1,232 @@
+/* $Id: inet_ntop.c,v 1.12 2009-11-02 11:55:54 yangtse Exp $ */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ares_ipv6.h"
+#include "inet_ntop.h"
+
+
+#ifndef HAVE_INET_NTOP
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
+static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ *     convert a network format address to presentation format.
+ * return:
+ *     pointer to presentation format address (`dst'), or NULL (see errno).
+ * note:
+ *      On Windows we store the error in the thread errno, not
+ *      in the winsock error code. This is to avoid loosing the
+ *      actual last winsock error. So use macro ERRNO to fetch the
+ *      errno this funtion sets when returning NULL, not SOCKERRNO.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+const char *
+ares_inet_ntop(int af, const void *src, char *dst, size_t size)
+{
+  switch (af)
+    {
+    case AF_INET:
+      return (inet_ntop4(src, dst, size));
+    case AF_INET6:
+      return (inet_ntop6(src, dst, size));
+    default:
+      SET_ERRNO(EAFNOSUPPORT);
+      return (NULL);
+    }
+  /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *     format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *     `dst' (as a const)
+ * notes:
+ *     (1) uses no statics
+ *     (2) takes a unsigned char* not an in_addr as input
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, size_t size)
+{
+  static const char fmt[] = "%u.%u.%u.%u";
+  char tmp[sizeof "255.255.255.255"];
+
+  if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size)
+    {
+      SET_ERRNO(ENOSPC);
+      return (NULL);
+    }
+    strcpy(dst, tmp);
+    return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *    convert IPv6 binary address into presentation (printable) format
+ * author:
+ *    Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, size_t size)
+{
+  /*
+   * Note that int32_t and int16_t need only be "at least" large enough
+   * to contain a value of the specified size.  On some systems, like
+   * Crays, there is no such thing as an integer variable with 16 bits.
+   * Keep this in mind if you think this function should have been coded
+   * to use pointer overlays.  All the world's not a VAX.
+   */
+  char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+  char *tp;
+  struct {
+    long base;
+    long len;
+  } best, cur;
+  unsigned long words[NS_IN6ADDRSZ / NS_INT16SZ];
+  int i;
+
+  /*
+   * Preprocess:
+   *  Copy the input (bytewise) array into a wordwise array.
+   *  Find the longest run of 0x00's in src[] for :: shorthanding.
+   */
+  memset(words, '\0', sizeof(words));
+  for (i = 0; i < NS_IN6ADDRSZ; i++)
+      words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+
+  best.base = -1;
+  cur.base = -1;
+  best.len = 0;
+  cur.len = 0;
+
+  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
+    {
+      if (words[i] == 0)
+        {
+          if (cur.base == -1)
+            cur.base = i, cur.len = 1;
+          else
+            cur.len++;
+        }
+      else
+        {
+          if (cur.base != -1)
+            {
+              if (best.base == -1 || cur.len > best.len)
+                best = cur;
+              cur.base = -1;
+            }
+        }
+    }
+  if (cur.base != -1)
+    {
+      if (best.base == -1 || cur.len > best.len)
+        best = cur;
+    }
+  if (best.base != -1 && best.len < 2)
+    best.base = -1;
+
+  /*
+   * Format the result.
+   */
+  tp = tmp;
+  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
+    {
+      /* Are we inside the best run of 0x00's? */
+      if (best.base != -1 && i >= best.base &&
+          i < (best.base + best.len))
+        {
+          if (i == best.base)
+             *tp++ = ':';
+          continue;
+        }
+      /* Are we following an initial run of 0x00s or any real hex? */
+      if (i != 0)
+        *tp++ = ':';
+      /* Is this address an encapsulated IPv4? */
+      if (i == 6 && best.base == 0 &&
+          (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
+        {
+          if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
+            return (NULL);
+          tp += strlen(tp);
+          break;
+        }
+        tp += SPRINTF((tp, "%lx", words[i]));
+    }
+
+  /* Was it a trailing run of 0x00's? */
+  if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
+    *tp++ = ':';
+  *tp++ = '\0';
+
+  /*
+   * Check for overflow, copy, and we're done.
+   */
+  if ((size_t)(tp - tmp) > size)
+    {
+      SET_ERRNO(ENOSPC);
+      return (NULL);
+    }
+  strcpy(dst, tmp);
+  return (dst);
+}
+#endif
+
diff --git a/3rdParty/CAres/src/inet_ntop.h b/3rdParty/CAres/src/inet_ntop.h
new file mode 100644
index 0000000..923689e
--- /dev/null
+++ b/3rdParty/CAres/src/inet_ntop.h
@@ -0,0 +1,27 @@
+#ifndef __ARES_INET_NTOP_H
+#define __ARES_INET_NTOP_H
+
+/* $Id: inet_ntop.h,v 1.4 2008-09-24 16:43:12 yangtse Exp $ */
+
+/* Copyright (C) 2005 by Dominick Meglio
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifdef HAVE_INET_NTOP
+#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)
+#else
+const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
+#endif /* __ARES_INET_NTOP_H */
diff --git a/3rdParty/CAres/src/nameser.h b/3rdParty/CAres/src/nameser.h
new file mode 100644
index 0000000..db324c0
--- /dev/null
+++ b/3rdParty/CAres/src/nameser.h
@@ -0,0 +1,194 @@
+/* $Id: nameser.h,v 1.29 2008-09-17 01:02:57 yangtse Exp $ */
+
+#ifndef ARES_NAMESER_H
+#define ARES_NAMESER_H
+
+/* header file provided by liren@vivisimo.com */
+
+#ifndef HAVE_ARPA_NAMESER_H
+
+#define NS_PACKETSZ     512   /* maximum packet size */
+#define NS_MAXDNAME     256   /* maximum domain name */
+#define NS_MAXCDNAME    255   /* maximum compressed domain name */
+#define NS_MAXLABEL     63
+#define NS_HFIXEDSZ     12    /* #/bytes of fixed data in header */
+#define NS_QFIXEDSZ     4     /* #/bytes of fixed data in query */
+#define NS_RRFIXEDSZ    10    /* #/bytes of fixed data in r record */
+#define NS_INT16SZ      2
+#define NS_INADDRSZ     4
+#define NS_IN6ADDRSZ    16
+#define NS_CMPRSFLGS    0xc0  /* Flag bits indicating name compression. */
+#define NS_DEFAULTPORT  53    /* For both TCP and UDP. */
+
+typedef enum __ns_class {
+    ns_c_invalid = 0,       /* Cookie. */
+    ns_c_in = 1,            /* Internet. */
+    ns_c_2 = 2,             /* unallocated/unsupported. */
+    ns_c_chaos = 3,         /* MIT Chaos-net. */
+    ns_c_hs = 4,            /* MIT Hesiod. */
+    /* Query class values which do not appear in resource records */
+    ns_c_none = 254,        /* for prereq. sections in update requests */
+    ns_c_any = 255,         /* Wildcard match. */
+    ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_type {
+    ns_t_invalid = 0,       /* Cookie. */
+    ns_t_a = 1,             /* Host address. */
+    ns_t_ns = 2,            /* Authoritative server. */
+    ns_t_md = 3,            /* Mail destination. */
+    ns_t_mf = 4,            /* Mail forwarder. */
+    ns_t_cname = 5,         /* Canonical name. */
+    ns_t_soa = 6,           /* Start of authority zone. */
+    ns_t_mb = 7,            /* Mailbox domain name. */
+    ns_t_mg = 8,            /* Mail group member. */
+    ns_t_mr = 9,            /* Mail rename name. */
+    ns_t_null = 10,         /* Null resource record. */
+    ns_t_wks = 11,          /* Well known service. */
+    ns_t_ptr = 12,          /* Domain name pointer. */
+    ns_t_hinfo = 13,        /* Host information. */
+    ns_t_minfo = 14,        /* Mailbox information. */
+    ns_t_mx = 15,           /* Mail routing information. */
+    ns_t_txt = 16,          /* Text strings. */
+    ns_t_rp = 17,           /* Responsible person. */
+    ns_t_afsdb = 18,        /* AFS cell database. */
+    ns_t_x25 = 19,          /* X_25 calling address. */
+    ns_t_isdn = 20,         /* ISDN calling address. */
+    ns_t_rt = 21,           /* Router. */
+    ns_t_nsap = 22,         /* NSAP address. */
+    ns_t_nsap_ptr = 23,     /* Reverse NSAP lookup (deprecated). */
+    ns_t_sig = 24,          /* Security signature. */
+    ns_t_key = 25,          /* Security key. */
+    ns_t_px = 26,           /* X.400 mail mapping. */
+    ns_t_gpos = 27,         /* Geographical position (withdrawn). */
+    ns_t_aaaa = 28,         /* Ip6 Address. */
+    ns_t_loc = 29,          /* Location Information. */
+    ns_t_nxt = 30,          /* Next domain (security). */
+    ns_t_eid = 31,          /* Endpoint identifier. */
+    ns_t_nimloc = 32,       /* Nimrod Locator. */
+    ns_t_srv = 33,          /* Server Selection. */
+    ns_t_atma = 34,         /* ATM Address */
+    ns_t_naptr = 35,        /* Naming Authority PoinTeR */
+    ns_t_kx = 36,           /* Key Exchange */
+    ns_t_cert = 37,         /* Certification record */
+    ns_t_a6 = 38,           /* IPv6 address (deprecates AAAA) */
+    ns_t_dname = 39,        /* Non-terminal DNAME (for IPv6) */
+    ns_t_sink = 40,         /* Kitchen sink (experimentatl) */
+    ns_t_opt = 41,          /* EDNS0 option (meta-RR) */
+    ns_t_apl = 42,          /* Address prefix list (RFC3123) */
+    ns_t_tkey = 249,        /* Transaction key */
+    ns_t_tsig = 250,        /* Transaction signature. */
+    ns_t_ixfr = 251,        /* Incremental zone transfer. */
+    ns_t_axfr = 252,        /* Transfer zone of authority. */
+    ns_t_mailb = 253,       /* Transfer mailbox records. */
+    ns_t_maila = 254,       /* Transfer mail agent records. */
+    ns_t_any = 255,         /* Wildcard match. */
+    ns_t_zxfr = 256,        /* BIND-specific, nonstandard. */
+    ns_t_max = 65536
+} ns_type;
+
+typedef enum __ns_opcode {
+    ns_o_query = 0,         /* Standard query. */
+    ns_o_iquery = 1,        /* Inverse query (deprecated/unsupported). */
+    ns_o_status = 2,        /* Name server status query (unsupported). */
+                                /* Opcode 3 is undefined/reserved. */
+    ns_o_notify = 4,        /* Zone change notification. */
+    ns_o_update = 5,        /* Zone update message. */
+    ns_o_max = 6
+} ns_opcode;
+
+typedef enum __ns_rcode {
+    ns_r_noerror = 0,       /* No error occurred. */
+    ns_r_formerr = 1,       /* Format error. */
+    ns_r_servfail = 2,      /* Server failure. */
+    ns_r_nxdomain = 3,      /* Name error. */
+    ns_r_notimpl = 4,       /* Unimplemented. */
+    ns_r_refused = 5,       /* Operation refused. */
+    /* these are for BIND_UPDATE */
+    ns_r_yxdomain = 6,      /* Name exists */
+    ns_r_yxrrset = 7,       /* RRset exists */
+    ns_r_nxrrset = 8,       /* RRset does not exist */
+    ns_r_notauth = 9,       /* Not authoritative for zone */
+    ns_r_notzone = 10,      /* Zone of record different from zone section */
+    ns_r_max = 11,
+    /* The following are TSIG extended errors */
+    ns_r_badsig = 16,
+    ns_r_badkey = 17,
+    ns_r_badtime = 18
+} ns_rcode;
+
+#endif /* HAVE_ARPA_NAMESER_H */
+
+#ifndef HAVE_ARPA_NAMESER_COMPAT_H
+
+#define PACKETSZ         NS_PACKETSZ
+#define MAXDNAME         NS_MAXDNAME
+#define MAXCDNAME        NS_MAXCDNAME
+#define MAXLABEL         NS_MAXLABEL
+#define HFIXEDSZ         NS_HFIXEDSZ
+#define QFIXEDSZ         NS_QFIXEDSZ
+#define RRFIXEDSZ        NS_RRFIXEDSZ
+#define INDIR_MASK       NS_CMPRSFLGS
+#define NAMESERVER_PORT  NS_DEFAULTPORT
+
+#define QUERY           ns_o_query
+
+#define SERVFAIL        ns_r_servfail
+#define NOTIMP          ns_r_notimpl
+#define REFUSED         ns_r_refused
+#undef NOERROR /* it seems this is already defined in winerror.h */
+#define NOERROR         ns_r_noerror
+#define FORMERR         ns_r_formerr
+#define NXDOMAIN        ns_r_nxdomain
+
+#define C_IN            ns_c_in
+#define C_CHAOS         ns_c_chaos
+#define C_HS            ns_c_hs
+#define C_NONE          ns_c_none
+#define C_ANY           ns_c_any
+
+#define T_A             ns_t_a
+#define T_NS            ns_t_ns
+#define T_MD            ns_t_md
+#define T_MF            ns_t_mf
+#define T_CNAME         ns_t_cname
+#define T_SOA           ns_t_soa
+#define T_MB            ns_t_mb
+#define T_MG            ns_t_mg
+#define T_MR            ns_t_mr
+#define T_NULL          ns_t_null
+#define T_WKS           ns_t_wks
+#define T_PTR           ns_t_ptr
+#define T_HINFO         ns_t_hinfo
+#define T_MINFO         ns_t_minfo
+#define T_MX            ns_t_mx
+#define T_TXT           ns_t_txt
+#define T_RP            ns_t_rp
+#define T_AFSDB         ns_t_afsdb
+#define T_X25           ns_t_x25
+#define T_ISDN          ns_t_isdn
+#define T_RT            ns_t_rt
+#define T_NSAP          ns_t_nsap
+#define T_NSAP_PTR      ns_t_nsap_ptr
+#define T_SIG           ns_t_sig
+#define T_KEY           ns_t_key
+#define T_PX            ns_t_px
+#define T_GPOS          ns_t_gpos
+#define T_AAAA          ns_t_aaaa
+#define T_LOC           ns_t_loc
+#define T_NXT           ns_t_nxt
+#define T_EID           ns_t_eid
+#define T_NIMLOC        ns_t_nimloc
+#define T_SRV           ns_t_srv
+#define T_ATMA          ns_t_atma
+#define T_NAPTR         ns_t_naptr
+#define T_TSIG          ns_t_tsig
+#define T_IXFR          ns_t_ixfr
+#define T_AXFR          ns_t_axfr
+#define T_MAILB         ns_t_mailb
+#define T_MAILA         ns_t_maila
+#define T_ANY           ns_t_any
+
+#endif /* HAVE_ARPA_NAMESER_COMPAT_H */
+
+#endif /* ARES_NAMESER_H */
diff --git a/3rdParty/CAres/src/setup_once.h b/3rdParty/CAres/src/setup_once.h
new file mode 100644
index 0000000..9d93ebc
--- /dev/null
+++ b/3rdParty/CAres/src/setup_once.h
@@ -0,0 +1,444 @@
+#ifndef __SETUP_ONCE_H
+#define __SETUP_ONCE_H
+
+/* $Id: setup_once.h,v 1.36 2009-06-19 00:41:03 yangtse Exp $ */
+
+/* Copyright (C) 2004 - 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+/********************************************************************
+ *                              NOTICE                              *
+ *                             ========                             *
+ *                                                                  *
+ *  Content of header files lib/setup_once.h and ares/setup_once.h  *
+ *  must be kept in sync. Modify the other one if you change this.  *
+ *                                                                  *
+ ********************************************************************/
+
+
+/*
+ * Inclusion of common header files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#else
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
+
+
+/*
+ * Definition of timeval struct for platforms that don't have it.
+ */
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif
+
+
+/*
+ * If we have the MSG_NOSIGNAL define, make sure we use
+ * it as the fourth argument of function send()
+ */
+
+#ifdef HAVE_MSG_NOSIGNAL
+#define SEND_4TH_ARG MSG_NOSIGNAL
+#else
+#define SEND_4TH_ARG 0
+#endif
+
+
+#if defined(__minix)
+/* Minix doesn't support recv on TCP sockets */
+#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z))
+
+#elif defined(HAVE_RECV)
+/*
+ * The definitions for the return type and arguments types
+ * of functions recv() and send() belong and come from the
+ * configuration file. Do not define them in any other place.
+ *
+ * HAVE_RECV is defined if you have a function named recv()
+ * which is used to read incoming data from sockets. If your
+ * function has another name then don't define HAVE_RECV.
+ *
+ * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
+ * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
+ * be defined.
+ *
+ * HAVE_SEND is defined if you have a function named send()
+ * which is used to write outgoing data on a connected socket.
+ * If yours has another name then don't define HAVE_SEND.
+ *
+ * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
+ * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
+ * SEND_TYPE_RETV must also be defined.
+ */
+
+#if !defined(RECV_TYPE_ARG1) || \
+    !defined(RECV_TYPE_ARG2) || \
+    !defined(RECV_TYPE_ARG3) || \
+    !defined(RECV_TYPE_ARG4) || \
+    !defined(RECV_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recv
+  /* */
+#else
+#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z), \
+                                   (RECV_TYPE_ARG4)(0))
+#endif
+#else /* HAVE_RECV */
+#ifndef sread
+  /* */
+  Error Missing_definition_of_macro_sread
+  /* */
+#endif
+#endif /* HAVE_RECV */
+
+
+#if defined(__minix)
+/* Minix doesn't support send on TCP sockets */
+#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+                                    (SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z))
+
+#elif defined(HAVE_SEND)
+#if !defined(SEND_TYPE_ARG1) || \
+    !defined(SEND_QUAL_ARG2) || \
+    !defined(SEND_TYPE_ARG2) || \
+    !defined(SEND_TYPE_ARG3) || \
+    !defined(SEND_TYPE_ARG4) || \
+    !defined(SEND_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_send
+  /* */
+#else
+#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+                                    (SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z), \
+                                    (SEND_TYPE_ARG4)(SEND_4TH_ARG))
+#endif
+#else /* HAVE_SEND */
+#ifndef swrite
+  /* */
+  Error Missing_definition_of_macro_swrite
+  /* */
+#endif
+#endif /* HAVE_SEND */
+
+
+#if 0
+#if defined(HAVE_RECVFROM)
+/*
+ * Currently recvfrom is only used on udp sockets.
+ */
+#if !defined(RECVFROM_TYPE_ARG1) || \
+    !defined(RECVFROM_TYPE_ARG2) || \
+    !defined(RECVFROM_TYPE_ARG3) || \
+    !defined(RECVFROM_TYPE_ARG4) || \
+    !defined(RECVFROM_TYPE_ARG5) || \
+    !defined(RECVFROM_TYPE_ARG6) || \
+    !defined(RECVFROM_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recvfrom
+  /* */
+#else
+#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1)  (s),  \
+                                                 (RECVFROM_TYPE_ARG2 *)(b),  \
+                                                 (RECVFROM_TYPE_ARG3)  (bl), \
+                                                 (RECVFROM_TYPE_ARG4)  (0),  \
+                                                 (RECVFROM_TYPE_ARG5 *)(f),  \
+                                                 (RECVFROM_TYPE_ARG6 *)(fl))
+#endif
+#else /* HAVE_RECVFROM */
+#ifndef sreadfrom
+  /* */
+  Error Missing_definition_of_macro_sreadfrom
+  /* */
+#endif
+#endif /* HAVE_RECVFROM */
+
+
+#ifdef RECVFROM_TYPE_ARG6_IS_VOID
+#  define RECVFROM_ARG6_T int
+#else
+#  define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
+#endif
+#endif /* if 0 */
+
+
+/*
+ * Function-like macro definition used to close a socket.
+ */
+
+#if defined(HAVE_CLOSESOCKET)
+#  define sclose(x)  closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+#  define sclose(x)  CloseSocket((x))
+#else
+#  define sclose(x)  close((x))
+#endif
+
+
+/*
+ * Uppercase macro versions of ANSI/ISO is*() functions/macros which
+ * avoid negative number inputs with argument byte codes > 127.
+ */
+
+#define ISSPACE(x)  (isspace((int)  ((unsigned char)x)))
+#define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x)))
+#define ISALNUM(x)  (isalnum((int)  ((unsigned char)x)))
+#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x)))
+#define ISALPHA(x)  (isalpha((int)  ((unsigned char)x)))
+#define ISPRINT(x)  (isprint((int)  ((unsigned char)x)))
+#define ISUPPER(x)  (isupper((int)  ((unsigned char)x)))
+#define ISLOWER(x)  (islower((int)  ((unsigned char)x)))
+
+#define ISBLANK(x)  (int)((((unsigned char)x) == ' ') || \
+                          (((unsigned char)x) == '\t'))
+
+
+/*
+ * Typedef to 'unsigned char' if bool is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_BOOL_T
+typedef unsigned char bool;
+#define HAVE_BOOL_T
+#endif
+
+
+/*
+ * Default definition of uppercase TRUE and FALSE.
+ */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+/*
+ * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#define HAVE_SIG_ATOMIC_T
+#endif
+
+
+/*
+ * Convenience SIG_ATOMIC_T definition
+ */
+
+#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
+#define SIG_ATOMIC_T static sig_atomic_t
+#else
+#define SIG_ATOMIC_T static volatile sig_atomic_t
+#endif
+
+
+/*
+ * Default return type for signal handlers.
+ */
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+
+/*
+ * Macro used to include code only in debug builds.
+ */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } while (0)
+#endif
+
+
+/*
+ * Macro used to include assertion code only in debug builds.
+ */
+
+#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
+#define DEBUGASSERT(x) assert(x)
+#else
+#define DEBUGASSERT(x) do { } while (0)
+#endif
+
+
+/*
+ * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef USE_WINSOCK
+#define SOCKERRNO         ((int)WSAGetLastError())
+#define SET_SOCKERRNO(x)  (WSASetLastError((int)(x)))
+#else
+#define SOCKERRNO         (errno)
+#define SET_SOCKERRNO(x)  (errno = (x))
+#endif
+
+
+/*
+ * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef WIN32
+#define ERRNO         ((int)GetLastError())
+#define SET_ERRNO(x)  (SetLastError((DWORD)(x)))
+#else
+#define ERRNO         (errno)
+#define SET_ERRNO(x)  (errno = (x))
+#endif
+
+
+/*
+ * Portable error number symbolic names defined to Winsock error codes.
+ */
+
+#ifdef USE_WINSOCK
+#undef  EBADF            /* override definition in errno.h */
+#define EBADF            WSAEBADF
+#undef  EINTR            /* override definition in errno.h */
+#define EINTR            WSAEINTR
+#undef  EINVAL           /* override definition in errno.h */
+#define EINVAL           WSAEINVAL
+#define EWOULDBLOCK      WSAEWOULDBLOCK
+#define EINPROGRESS      WSAEINPROGRESS
+#define EALREADY         WSAEALREADY
+#define ENOTSOCK         WSAENOTSOCK
+#define EDESTADDRREQ     WSAEDESTADDRREQ
+#define EMSGSIZE         WSAEMSGSIZE
+#define EPROTOTYPE       WSAEPROTOTYPE
+#define ENOPROTOOPT      WSAENOPROTOOPT
+#define EPROTONOSUPPORT  WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT  WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP       WSAEOPNOTSUPP
+#define EPFNOSUPPORT     WSAEPFNOSUPPORT
+#define EAFNOSUPPORT     WSAEAFNOSUPPORT
+#define EADDRINUSE       WSAEADDRINUSE
+#define EADDRNOTAVAIL    WSAEADDRNOTAVAIL
+#define ENETDOWN         WSAENETDOWN
+#define ENETUNREACH      WSAENETUNREACH
+#define ENETRESET        WSAENETRESET
+#define ECONNABORTED     WSAECONNABORTED
+#define ECONNRESET       WSAECONNRESET
+#define ENOBUFS          WSAENOBUFS
+#define EISCONN          WSAEISCONN
+#define ENOTCONN         WSAENOTCONN
+#define ESHUTDOWN        WSAESHUTDOWN
+#define ETOOMANYREFS     WSAETOOMANYREFS
+#define ETIMEDOUT        WSAETIMEDOUT
+#define ECONNREFUSED     WSAECONNREFUSED
+#define ELOOP            WSAELOOP
+#ifndef ENAMETOOLONG     /* possible previous definition in errno.h */
+#define ENAMETOOLONG     WSAENAMETOOLONG
+#endif
+#define EHOSTDOWN        WSAEHOSTDOWN
+#define EHOSTUNREACH     WSAEHOSTUNREACH
+#ifndef ENOTEMPTY        /* possible previous definition in errno.h */
+#define ENOTEMPTY        WSAENOTEMPTY
+#endif
+#define EPROCLIM         WSAEPROCLIM
+#define EUSERS           WSAEUSERS
+#define EDQUOT           WSAEDQUOT
+#define ESTALE           WSAESTALE
+#define EREMOTE          WSAEREMOTE
+#endif
+
+
+/*
+ *  Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
+ */
+
+#if defined(VMS) && \
+    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#define getpwuid __32_getpwuid
+#endif
+
+
+/*
+ * Macro argv_item_t hides platform details to code using it.
+ */
+
+#ifdef VMS
+#define argv_item_t  __char_ptr32
+#else
+#define argv_item_t  char *
+#endif
+
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+
+#endif /* __SETUP_ONCE_H */
+
diff --git a/3rdParty/CAres/src/windows_port.c b/3rdParty/CAres/src/windows_port.c
new file mode 100644
index 0000000..ce129ae
--- /dev/null
+++ b/3rdParty/CAres/src/windows_port.c
@@ -0,0 +1,23 @@
+#include "ares_setup.h"
+
+/* $Id: windows_port.c,v 1.22 2009-11-02 11:55:54 yangtse Exp $ */
+
+/* only do the following on windows
+ */
+#if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS)
+
+#ifdef __WATCOMC__
+/*
+ * Watcom needs a DllMain() in order to initialise the clib startup code.
+ */
+BOOL
+WINAPI DllMain (HINSTANCE hnd, DWORD reason, LPVOID reserved)
+{
+  (void) hnd;
+  (void) reason;
+  (void) reserved;
+  return (TRUE);
+}
+#endif
+
+#endif /* WIN32 builds only */
diff --git a/SConstruct b/SConstruct
index 6cd55aa..e4866e0 100644
--- a/SConstruct
+++ b/SConstruct
@@ -321,6 +321,7 @@ SConscript(dirs = [
 		"3rdParty/CppUnit",
 		"3rdParty/Boost",
 		"3rdParty/LibIDN",
+		#"3rdParty/CAres",
 		"3rdParty/SQLite"])
 
 # Checker
-- 
cgit v0.10.2-6-g49f6