Commit 6e4788dd authored by Mark Andrews's avatar Mark Andrews

4448. [bug] win32: ::1 was not being found when iterating

                        interfaces. [RT #42993]
parent 81ace511
4448. [bug] win32: ::1 was not being found when iterating
interfaces. [RT #42993]
4447. [tuning] Allow the fstrm_iothr_init() options to be set using
named.conf to control how dnstap manages the data
flow. [RT #42974]
......
......@@ -52,15 +52,17 @@ struct isc_interfaceiter {
unsigned int magic; /* Magic number. */
isc_mem_t *mctx;
SOCKET socket;
INTERFACE_INFO IFData; /* Current Interface Info */
int numIF; /* Current Interface count */
INTERFACE_INFO IFData; /* Current Interface Info. */
int numIF; /* Current Interface count. */
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;
SOCKET_ADDRESS_LIST *buf6; /* Buffer for WSAIoctl data. */
unsigned int buf6size; /* Bytes allocated. */
unsigned int pos6;
unsigned int pos6; /* Which entry to process. */
isc_boolean_t v6loop; /* See IPv6 loop address. */
isc_boolean_t pos6zero; /* Done pos6 == 0. */
isc_interface_t current; /* Current interface data. */
isc_result_t result; /* Last result code. */
};
......@@ -119,6 +121,8 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
iter->buf6 = NULL;
iter->pos4 = NULL;
iter->pos6 = 0;
iter->v6loop = ISC_TRUE;
iter->pos6zero = ISC_TRUE;
iter->buf6size = 0;
iter->buf4size = 0;
iter->result = ISC_R_FAILURE;
......@@ -327,14 +331,15 @@ internal_current(isc_interfaceiter_t *iter) {
if ((flags & IFF_POINTTOPOINT) != 0) {
iter->current.flags |= INTERFACE_F_POINTTOPOINT;
sprintf(iter->current.name, "PPP Interface %d", iter->numIF);
snprintf(iter->current.name, sizeof(iter->current.name),
"PPP Interface %d", iter->numIF);
ifNamed = TRUE;
}
if ((flags & IFF_LOOPBACK) != 0) {
iter->current.flags |= INTERFACE_F_LOOPBACK;
sprintf(iter->current.name, "Loopback Interface %d",
iter->numIF);
snprintf(iter->current.name, sizeof(iter->current.name),
"Loopback Interface %d", iter->numIF);
ifNamed = TRUE;
}
......@@ -347,7 +352,7 @@ internal_current(isc_interfaceiter_t *iter) {
}
if (ifNamed == FALSE)
sprintf(iter->current.name,
snprintf(iter->current.name, sizeof(iter->current.name),
"TCP/IP Interface %d", iter->numIF);
/*
......@@ -361,32 +366,68 @@ internal_current(isc_interfaceiter_t *iter) {
static isc_result_t
internal_current6(isc_interfaceiter_t *iter) {
BOOL ifNamed = FALSE;
SOCKET fd;
int i;
REQUIRE(VALID_IFITER(iter));
REQUIRE(iter->pos6 >= 0);
REQUIRE(iter->buf6 != 0);
REQUIRE(iter->buf6 != NULL);
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;
if (iter->pos6 != 0U || !iter->pos6zero) {
if (iter->pos6 == 0U)
iter->pos6zero = ISC_TRUE;
get_addr(AF_INET6, &iter->current.address,
iter->buf6->Address[iter->pos6].lpSockaddr);
/*
* Set interface flags.
*/
iter->current.flags = INTERFACE_F_UP;
snprintf(iter->current.name, sizeof(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;
if (IN6_IS_ADDR_LOOPBACK(&iter->current.address.type.in6))
iter->v6loop = ISC_TRUE;
} else {
/*
* See if we can bind to the ::1 and if so return ::1.
*/
struct sockaddr_in6 sin6;
iter->v6loop = ISC_TRUE; /* So we don't loop forever. */
fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd == INVALID_SOCKET)
return (ISC_R_IGNORE);
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_addr.s6_addr[15] = 1;
if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
closesocket(fd);
return (ISC_R_IGNORE);
}
closesocket(fd);
iter->current.flags = INTERFACE_F_UP | INTERFACE_F_LOOPBACK;
snprintf(iter->current.name, sizeof(iter->current.name),
"TCP/IPv6 Loopback Interface");
for (i = 0; i < 16; i++) {
if (i != 15)
iter->current.address.type.in6.s6_addr[i] = 0;
else
iter->current.address.type.in6.s6_addr[i] = 1;
iter->current.netmask.type.in6.s6_addr[i] = 0xff;
}
iter->current.address.family = AF_INET6;
iter->current.netmask.family = AF_INET6;
}
return (ISC_R_SUCCESS);
}
......@@ -425,9 +466,10 @@ internal_next(isc_interfaceiter_t *iter) {
static isc_result_t
internal_next6(isc_interfaceiter_t *iter) {
if (iter->pos6 == 0)
if (iter->pos6 == 0 && iter->v6loop)
return (ISC_R_NOMORE);
iter->pos6--;
if (iter->pos6 != 0)
iter->pos6--;
return (ISC_R_SUCCESS);
}
......@@ -444,8 +486,11 @@ isc_interfaceiter_first(isc_interfaceiter_t *iter) {
REQUIRE(VALID_IFITER(iter));
if (iter->buf6 != NULL)
if (iter->buf6 != NULL) {
iter->pos6 = iter->buf6->iAddressCount;
iter->v6loop = ISC_FALSE;
iter->pos6zero = ISC_FALSE;
}
iter->result = ISC_R_SUCCESS;
return (isc_interfaceiter_next(iter));
}
......@@ -464,8 +509,9 @@ isc_interfaceiter_next(isc_interfaceiter_t *iter) {
if (result != ISC_R_SUCCESS)
break;
result = internal_current6(iter);
if (result != ISC_R_IGNORE)
break;
if (result == ISC_R_IGNORE)
continue;
break;
} else if (result != ISC_R_SUCCESS)
break;
result = internal_current(iter);
......
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