[Patch] gethostbyname2
Pierre A. Humblet
pierre@phumblet.no-ip.org
Thu Feb 26 04:03:00 GMT 2009
I tried to compile Exim with IPv6 enabled and Cygwin 1.7, but it
needs gethostbyname2.
Here is an implementation of that function.
In attachment I am including the same patch as well as a short test function.
Pierre
2009-02-25 Pierre Humblet <Pierre.Humblet@ieee.org>
* net.cc: Include windns.h.
(gethostbyname2): New function.
* cygwin.din: Export gethostbyname2.
Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.202
diff -u -p -r1.202 cygwin.din
--- cygwin.din 19 Feb 2009 09:22:51 -0000 1.202
+++ cygwin.din 26 Feb 2009 03:54:30 -0000
@@ -635,6 +635,7 @@ _getgroups = getgroups SIGFE
_getgroups32 = getgroups32 SIGFE
gethostbyaddr = cygwin_gethostbyaddr SIGFE
gethostbyname = cygwin_gethostbyname SIGFE
+gethostbyname2 SIGFE
gethostid SIGFE
gethostname = cygwin_gethostname SIGFE
_gethostname = cygwin_gethostname SIGFE
Index: net.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/net.cc,v
retrieving revision 1.248
diff -u -p -r1.248 net.cc
--- net.cc 16 Sep 2008 02:04:27 -0000 1.248
+++ net.cc 26 Feb 2009 03:54:31 -0000
@@ -25,6 +25,7 @@ details. */
#include <netdb.h>
#define USE_SYS_TYPES_FD_SET
#include <winsock2.h>
+#include <windns.h>
#include <iphlpapi.h>
#include <assert.h>
#include "cygerrno.h"
@@ -888,6 +889,157 @@ cygwin_gethostbyaddr (const char *addr,
return res;
}
+/* gethostbyname2: standards? */
+extern "C" struct hostent *
+gethostbyname2 (const char *name, int af)
+{
+ sig_dispatch_pending ();
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return NULL;
+
+ DWORD type;
+ hostent tmp, *h = NULL;
+ tmp.h_name = NULL;
+ tmp.h_aliases = NULL;
+ tmp.h_addrtype = af;
+ switch (af)
+ {
+ case AF_INET:
+ tmp.h_length = sizeof (IP4_ADDRESS);
+ type = DNS_TYPE_A;
+ break;
+ case AF_INET6:
+ tmp.h_length = sizeof (IP6_ADDRESS);
+ type = DNS_TYPE_AAAA;
+ break;
+ default:
+ set_errno (EAFNOSUPPORT);
+ h_errno = NETDB_INTERNAL;
+ return NULL;
+ }
+
+ PDNS_RECORD pQueryResultsSet, rr;
+ /* Normal query, including search */
+ DNS_STATUS res = DnsQuery_A (name, type, DNS_QUERY_STANDARD,
+ NULL, &pQueryResultsSet, NULL);
+
+ debug_printf ("DnsQuery: %s type = %d res = %lu\n", name, type, res);
+
+ // NETDB_INTERNAL -1 /* see errno */
+ // HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+ // TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+ // NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+ // NO_DATA 4 /* Valid name, no data record of requested type */
+
+ switch (res)
+ {
+ case ERROR_SUCCESS:
+ break;
+ case ERROR_INVALID_NAME:
+ set_errno (EINVAL);
+ h_errno = NETDB_INTERNAL;;
+ return NULL;
+ case ERROR_TIMEOUT:
+ case DNS_ERROR_RCODE_SERVER_FAILURE:
+ h_errno = TRY_AGAIN;
+ return NULL;
+ case DNS_ERROR_RCODE_NAME_ERROR:
+ h_errno = HOST_NOT_FOUND;
+ return NULL;
+ case DNS_ERROR_NO_DNS_SERVERS:
+ case DNS_ERROR_RCODE_FORMAT_ERROR:
+ case DNS_ERROR_RCODE_NOT_IMPLEMENTED:
+ case DNS_ERROR_RCODE_REFUSED:
+ h_errno = NO_RECOVERY;
+ return NULL;
+ case DNS_INFO_NO_RECORDS: /* May be returned when the host
doesn't exist */
+ h_errno = NO_DATA;
+ return NULL;
+ default:
+ debug_printf ("Unknown code\n");
+ h_errno = NO_RECOVERY;
+ return NULL;
+ }
+
+ const int RECORD_INC = 16;
+ int record_size = 0;
+ int alias_count = 0;
+ int address_count = 0;
+ for (rr = pQueryResultsSet; rr; rr = rr->pNext)
+ {
+ debug_printf ("%s Section %d Type %u Size %d\n",
+ rr->pName, rr->Flags.S.Section, rr->wType, rr->wDataLength);
+ /* Normally DnsQuery does not provide Question section records and we
+ should only consider Answer section records.
+ However DnsQuery seems to return only Question records (with data)
+ for local names and numeric addresses */
+ if (!((rr->Flags.S.Section == DnsSectionAnswer)
+ || (rr->Flags.S.Section == DnsSectionQuestion)))
+ continue;
+
+ /* Alloc space, including two null entries */
+ if ((alias_count + address_count + 2) >= record_size)
+ {
+ void * ptr = realloc (tmp.h_aliases,
+ sizeof (char *)*(record_size += RECORD_INC));
+ if (!ptr)
+ {
+ h_errno = NETDB_INTERNAL;
+ address_count = -1; /* Flag error */
+ break;
+ }
+ tmp.h_aliases = (char **) ptr;
+ }
+
+ switch (rr->wType)
+ {
+ case DNS_TYPE_CNAME:
+ /* The CNAME records are supposed to form a chain.
+ We trust the resolver.
+ Move the addresses. This should never be needed. */
+ for (int i = address_count; i > 0; i--)
+ tmp.h_aliases[alias_count + 1 + i] = tmp.h_aliases[alias_count + i];
+ tmp.h_aliases[alias_count++] = rr->pName;
+ break;
+ case DNS_TYPE_A:
+ /* The address records should all have as pName the last canonical name.
+ We trust the resolver */
+ if ((af == AF_INET)
+ && (rr->wDataLength == sizeof (IP4_ADDRESS)))
+ {
+ tmp.h_aliases[alias_count + ++address_count] = (char *) &
rr->Data.A.IpAddress;
+ tmp.h_name = rr->pName;
+ }
+ break;
+ case DNS_TYPE_AAAA:
+ if ((af == AF_INET6)
+ && (rr->wDataLength == sizeof (IP6_ADDRESS)))
+ {
+ tmp.h_aliases[alias_count + ++address_count] = (char *) &
rr->Data.AAAA.Ip6Address;
+ tmp.h_name = rr->pName;
+ }
+ break;
+ default:
+ continue;
+ }
+ }
+
+ if (address_count == 0)
+ h_errno = NO_DATA;
+ else if (address_count > 0)
+ {
+ tmp.h_aliases[alias_count] = NULL;
+ tmp.h_addr_list = & tmp.h_aliases[alias_count + 1];
+ tmp.h_addr_list[address_count] = NULL;
+ if (!(h = dup_ent (&tmp)))
+ h_errno = NETDB_INTERNAL;
+ }
+ DnsRecordListFree (pQueryResultsSet, DnsFreeRecordList);
+ free (tmp.h_aliases);
+ return h;
+}
+
/* exported as accept: standards? */
extern "C" int
cygwin_accept (int fd, struct sockaddr *peer, socklen_t *len)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: try_gethostbyname.c
Type: application/octet-stream
Size: 1008 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20090226/5ad49eb3/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: net.cc
Type: application/octet-stream
Size: 113672 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20090226/5ad49eb3/attachment-0001.obj>
More information about the Cygwin-patches
mailing list