This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] gethostbyname2


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)

Attachment: try_gethostbyname.c
Description: Binary data

Attachment: net.cc
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]