Commit 07555e64 authored by Mark Andrews's avatar Mark Andrews
Browse files

2350. [port] win32: IPv6 support. [RT #17797]

parent 3f42cf2f
2350. [port] win32: IPv6 support. [RT #17797]
2349. [func] Provide incremental re-signing support for secure
dynamic zones. [RT #1091]
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: config.h.win32,v 1.16 2007/06/19 23:46:59 tbox Exp $ */
/* $Id: config.h.win32,v 1.17 2008/04/02 02:56:23 marka Exp $ */
/*
* win32 configuration file
......@@ -123,9 +123,7 @@
/* Define if you have DH_generate_parameters(). */
#define HAVE_DH_GENERATE_PARAMETERS
#define ISC_PLATFORM_NEEDSTRLCAT
#define ISC_PLATFORM_NEEDSTRLCPY
#define WANT_IPV6
#define S_IFMT _S_IFMT /* file type mask */
#define S_IFDIR _S_IFDIR /* directory */
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.362 2008/03/31 05:00:30 marka Exp $ */
/* $Id: resolver.c,v 1.363 2008/04/02 02:56:23 marka Exp $ */
/*! \file */
......@@ -2271,6 +2271,13 @@ fctx_getaddresses(fetchctx_t *fctx) {
}
while (sa != NULL) {
if ((isc_sockaddr_pf(sa) == AF_INET &&
fctx->res->dispatchv4 == NULL) ||
(isc_sockaddr_pf(sa) == AF_INET6 &&
fctx->res->dispatchv6 == NULL)) {
sa = ISC_LIST_NEXT(sa, link);
continue;
}
ai = NULL;
result = dns_adb_findaddrinfo(fctx->adb,
sa, &ai, 0); /* XXXMLG */
......
......@@ -694,10 +694,10 @@ SOURCE=..\gssapictx.c
# End Source File
# Begin Source File
SOURCE=..\spnego.c
# End Source File
# Begin Source File
SOURCE=..\spnego.c
# End Source File
# Begin Source File
SOURCE=..\hmac_link.c
# End Source File
# Begin Source File
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: platform.h,v 1.14 2007/06/19 23:47:20 tbox Exp $ */
/* $Id: platform.h,v 1.15 2008/04/02 02:56:23 marka Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
......@@ -34,6 +34,7 @@
#if _MSC_VER > 1200
#define ISC_PLATFORM_HAVEIN6PKTINFO
#endif
#define ISC_PLATFORM_HAVESCOPEID
#define ISC_PLATFORM_NEEDPORTT
#undef MSG_TRUNC
#define ISC_PLATFORM_NEEDNTOP
......@@ -44,6 +45,8 @@
#define ISC_PLATFORM_NEEDSTRSEP
#define ISC_PLATFORM_NEEDSTRLCPY
#define ISC_PLATFORM_NEEDSTRLCAT
#define ISC_PLATFORM_NEEDSTRLCPY
/*
* Used to control how extern data is linked; needed for Win32 platforms.
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: interfaceiter.c,v 1.10 2007/06/18 23:47:49 tbox Exp $ */
/* $Id: interfaceiter.c,v 1.11 2008/04/02 02:56:23 marka Exp $ */
/*
* Note that this code will need to be revisited to support IPv6 Interfaces.
......@@ -62,11 +62,13 @@ struct isc_interfaceiter {
int socket;
INTERFACE_INFO IFData; /* Current Interface Info */
int numIF; /* Current Interface count */
int totalIF; /* Total Number
of Interfaces */
INTERFACE_INFO *buf; /* Buffer for WSAIoctl data. */
unsigned int bufsize; /* Bytes allocated. */
INTERFACE_INFO *pos; /* Current offset in IF List */
int v4IF; /* Number of IPv4 Interfaces */
INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */
unsigned int buf4size; /* Bytes allocated. */
INTERFACE_INFO *pos4; /* Current offset in IF List */
SOCKET_ADDRESS_LIST *buf6;
unsigned int buf6size; /* Bytes allocated. */
unsigned int pos6;
isc_interface_t current; /* Current interface data. */
isc_result_t result; /* Last result code. */
};
......@@ -94,6 +96,7 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) {
memcpy(&dst->type.in6,
&((struct sockaddr_in6 *) src)->sin6_addr,
sizeof(struct in6_addr));
dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id;
break;
default:
INSIST(0);
......@@ -120,7 +123,15 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
InitSockets();
iter->mctx = mctx;
iter->buf = NULL;
iter->buf4 = NULL;
iter->buf6 = NULL;
iter->pos4 = NULL;
iter->pos6 = 0;
iter->buf6size = 0;
iter->buf4size = 0;
iter->result = ISC_R_FAILURE;
iter->numIF = 0;
iter->v4IF = 0;
/*
* Create an unbound datagram socket to do the
......@@ -128,6 +139,8 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
*/
if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error = WSAGetLastError();
if (error == WSAEAFNOSUPPORT)
goto inet6_only;
isc__strerror(error, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"making interface scan socket: %s",
......@@ -140,17 +153,17 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
* Get the interface configuration, allocating more memory if
* necessary.
*/
iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
for (;;) {
iter->buf = isc_mem_get(mctx, iter->bufsize);
if (iter->buf == NULL) {
iter->buf4 = isc_mem_get(mctx, iter->buf4size);
if (iter->buf4 == NULL) {
result = ISC_R_NOMEMORY;
goto alloc_failure;
}
if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST,
0, 0, iter->buf, iter->bufsize,
0, 0, iter->buf4, iter->buf4size,
&bytesReturned, 0, 0) == SOCKET_ERROR)
{
error = WSAGetLastError();
......@@ -174,19 +187,19 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
* case and retry.
*/
if (bytesReturned > 0 &&
(bytesReturned < iter->bufsize))
(bytesReturned < iter->buf4size))
break;
}
if (iter->bufsize >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"get interface configuration: "
"maximum buffer size exceeded");
result = ISC_R_UNEXPECTED;
goto ioctl_failure;
}
isc_mem_put(mctx, iter->buf, iter->bufsize);
isc_mem_put(mctx, iter->buf4, iter->buf4size);
iter->bufsize += IFCONF_SIZE_INCREMENT *
iter->buf4size += IFCONF_SIZE_INCREMENT *
sizeof(INTERFACE_INFO);
}
......@@ -194,23 +207,92 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
* A newly created iterator has an undefined position
* until isc_interfaceiter_first() is called.
*/
iter->pos = NULL;
iter->result = ISC_R_FAILURE;
iter->numIF = 0;
iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO);
iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
/* We don't need the socket any more, so close it */
closesocket(iter->socket);
inet6_only:
/*
* Create an unbound datagram socket to do the
* SIO_ADDRESS_LIST_QUERY WSAIoctl on.
*/
if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
error = WSAGetLastError();
if (error == WSAEAFNOSUPPORT)
goto inet_only;
isc__strerror(error, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"making interface scan socket: %s",
strbuf);
result = ISC_R_UNEXPECTED;
goto ioctl_failure;
}
/*
* Get the interface configuration, allocating more memory if
* necessary.
*/
iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
for (;;) {
iter->buf6 = isc_mem_get(mctx, iter->buf6size);
if (iter->buf6 == NULL) {
result = ISC_R_NOMEMORY;
goto ioctl_failure;
}
if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
0, 0, iter->buf6, iter->buf6size,
&bytesReturned, 0, 0) == SOCKET_ERROR)
{
error = WSAGetLastError();
if (error != WSAEFAULT && error != WSAENOBUFS) {
errno = error;
isc__strerror(error, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"sio address list query: %s",
strbuf);
result = ISC_R_UNEXPECTED;
goto ioctl6_failure;
}
/*
* EINVAL. Retry with a bigger buffer.
*/
} else
break;
if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"get interface configuration: "
"maximum buffer size exceeded");
result = ISC_R_UNEXPECTED;
goto ioctl6_failure;
}
isc_mem_put(mctx, iter->buf6, iter->buf6size);
iter->buf6size += IFCONF_SIZE_INCREMENT *
sizeof(SOCKET_ADDRESS);
}
closesocket(iter->socket);
inet_only:
iter->magic = IFITER_MAGIC;
*iterp = iter;
/* We don't need the socket any more, so close it */
closesocket(iter->socket);
return (ISC_R_SUCCESS);
ioctl6_failure:
isc_mem_put(mctx, iter->buf6, iter->buf6size);
ioctl_failure:
isc_mem_put(mctx, iter->buf, iter->bufsize);
if (iter->buf4 != NULL)
isc_mem_put(mctx, iter->buf4, iter->buf4size);
alloc_failure:
(void) closesocket(iter->socket);
if (iter->socket >= 0)
(void) closesocket(iter->socket);
socket_failure:
isc_mem_put(mctx, iter, sizeof(*iter));
......@@ -226,7 +308,7 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
*/
static isc_result_t
internal_current(isc_interfaceiter_t *iter, int family) {
internal_current(isc_interfaceiter_t *iter) {
BOOL ifNamed = FALSE;
unsigned long flags;
......@@ -234,9 +316,9 @@ internal_current(isc_interfaceiter_t *iter, int family) {
REQUIRE(iter->numIF >= 0);
memset(&iter->current, 0, sizeof(iter->current));
iter->current.af = family;
iter->current.af = AF_INET;
get_addr(family, &iter->current.address,
get_addr(AF_INET, &iter->current.address,
(struct sockaddr *)&(iter->IFData.iiAddress));
/*
......@@ -266,7 +348,7 @@ internal_current(isc_interfaceiter_t *iter, int family) {
* If the interface is point-to-point, get the destination address.
*/
if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
get_addr(family, &iter->current.dstaddress,
get_addr(AF_INET, &iter->current.dstaddress,
(struct sockaddr *)&(iter->IFData.iiBroadcastAddress));
}
......@@ -277,18 +359,43 @@ internal_current(isc_interfaceiter_t *iter, int family) {
/*
* Get the network mask.
*/
switch (family) {
case AF_INET:
get_addr(family, &iter->current.netmask,
(struct sockaddr *)&(iter->IFData.iiNetmask));
break;
case AF_INET6:
break;
}
get_addr(AF_INET, &iter->current.netmask,
(struct sockaddr *)&(iter->IFData.iiNetmask));
return (ISC_R_SUCCESS);
}
static isc_result_t
internal_current6(isc_interfaceiter_t *iter) {
BOOL ifNamed = FALSE;
int i;
REQUIRE(VALID_IFITER(iter));
REQUIRE(iter->pos6 >= 0);
REQUIRE(iter->buf6 != 0);
memset(&iter->current, 0, sizeof(iter->current));
iter->current.af = AF_INET6;
get_addr(AF_INET6, &iter->current.address,
iter->buf6->Address[iter->pos6].lpSockaddr);
/*
* Get interface flags.
*/
iter->current.flags = INTERFACE_F_UP;
if (ifNamed == FALSE)
sprintf(iter->current.name,
"TCP/IPv6 Interface %d", iter->pos6 + 1);
for (i = 0; i< 16; i++)
iter->current.netmask.type.in6.s6_addr[i] = 0xff;
iter->current.netmask.family = AF_INET6;
return (ISC_R_SUCCESS);
}
/*
* Step the iterator to the next interface. Unlike
* isc_interfaceiter_next(), this may leave the iterator
......@@ -298,7 +405,7 @@ internal_current(isc_interfaceiter_t *iter, int family) {
*/
static isc_result_t
internal_next(isc_interfaceiter_t *iter) {
if (iter->numIF >= iter->totalIF)
if (iter->numIF >= iter->v4IF)
return (ISC_R_NOMORE);
/*
......@@ -309,19 +416,26 @@ internal_next(isc_interfaceiter_t *iter) {
*/
if (iter->numIF == 0)
iter->pos = (INTERFACE_INFO *)(iter->buf + (iter->totalIF));
iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
iter->pos--;
if (&(iter->pos) < &(iter->buf))
iter->pos4--;
if (&(iter->pos4) < &(iter->buf4))
return (ISC_R_NOMORE);
memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO));
memcpy(&(iter->IFData), iter->pos, sizeof(INTERFACE_INFO));
memcpy(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO));
iter->numIF++;
return (ISC_R_SUCCESS);
}
internal_next6(isc_interfaceiter_t *iter) {
if (iter->pos6 == 0)
return (ISC_R_NOMORE);
iter->pos6--;
return (ISC_R_SUCCESS);
}
isc_result_t
isc_interfaceiter_current(isc_interfaceiter_t *iter,
isc_interface_t *ifdata) {
......@@ -332,21 +446,13 @@ isc_interfaceiter_current(isc_interfaceiter_t *iter,
isc_result_t
isc_interfaceiter_first(isc_interfaceiter_t *iter) {
isc_result_t result;
REQUIRE(VALID_IFITER(iter));
iter->numIF = 0;
for (;;) {
result = internal_next(iter);
if (result != ISC_R_SUCCESS)
break;
result = internal_current(iter, AF_INET);
if (result != ISC_R_IGNORE)
break;
}
iter->result = result;
return (result);
if (iter->buf6 != NULL)
iter->pos6 = iter->buf6->iAddressCount;
iter->result = ISC_R_SUCCESS;
return (isc_interfaceiter_next(iter));
}
isc_result_t
......@@ -358,9 +464,16 @@ isc_interfaceiter_next(isc_interfaceiter_t *iter) {
for (;;) {
result = internal_next(iter);
if (result != ISC_R_SUCCESS)
if (result == ISC_R_NOMORE) {
result = internal_next6(iter);
if (result != ISC_R_SUCCESS)
break;
result = internal_current6(iter);
if (result != ISC_R_IGNORE)
break;
} else if (result != ISC_R_SUCCESS)
break;
result = internal_current(iter,AF_INET);
result = internal_current(iter);
if (result != ISC_R_IGNORE)
break;
}
......@@ -375,10 +488,12 @@ isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) {
iter = *iterp;
REQUIRE(VALID_IFITER(iter));
isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
if (iter->buf4 != NULL)
isc_mem_put(iter->mctx, iter->buf4, iter->buf4size);
if (iter->buf6 != NULL)
isc_mem_put(iter->mctx, iter->buf6, iter->buf6size);
iter->magic = 0;
isc_mem_put(iter->mctx, iter, sizeof(*iter));
*iterp = NULL;
}
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: net.c,v 1.14 2007/06/18 23:47:49 tbox Exp $ */
/* $Id: net.c,v 1.15 2008/04/02 02:56:23 marka Exp $ */
#include <config.h>
......@@ -51,7 +51,7 @@ try_proto(int domain) {
char strbuf[ISC_STRERRORSIZE];
int errval;
s = socket(domain, SOCK_STREAM, 0);
s = socket(domain, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) {
errval = WSAGetLastError();
switch (errval) {
......@@ -72,53 +72,9 @@ try_proto(int domain) {
}
}
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
if (domain == PF_INET6) {
struct sockaddr_in6 sin6;
unsigned int len;
/*
* Check to see if IPv6 is broken, as is common on Linux.
*/
len = sizeof(sin6);
if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0)
{
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
"retrieving the address of an IPv6 "
"socket from the kernel failed.");
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
"IPv6 support is disabled.");
result = ISC_R_NOTFOUND;
} else {
if (len == sizeof(struct sockaddr_in6))
result = ISC_R_SUCCESS;
else {
isc_log_write(isc_lctx,
ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET,
ISC_LOG_ERROR,
"IPv6 structures in kernel and "
"user space do not match.");
isc_log_write(isc_lctx,
ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET,
ISC_LOG_ERROR,
"IPv6 support is disabled.");
result = ISC_R_NOTFOUND;
}
}
}
#endif
#endif
#endif
closesocket(s);
return (result);
return (ISC_R_SUCCESS);
}
static void
......@@ -198,7 +154,7 @@ try_ipv6only(void) {
goto close;
}
close(s);
closesocket(s);
/* check for UDP sockets */
s = socket(PF_INET6, SOCK_DGRAM, 0);
......@@ -221,12 +177,10 @@ try_ipv6only(void) {
goto close;
}
close(s);
ipv6only_result = ISC_R_SUCCESS;
close:
close(s);
closeocket(s);
return;
#endif /* IPV6_V6ONLY */
}
......@@ -252,7 +206,7 @@ try_ipv6pktinfo(void) {
/* we only use this for UDP sockets */
s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
if (s == INVALID_SOCKET) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"socket() %s: %s",
......@@ -276,11 +230,10 @@ try_ipv6pktinfo(void) {
goto close;
}
close(s);
ipv6pktinfo_result = ISC_R_SUCCESS;
close:
close(s);
closesocket(s);
return;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment